zoukankan      html  css  js  c++  java
  • Hibernate 一对多/多对多

    一对多关联(多对一):

        一对多关联映射:
            在多的一端添加一个外键指向一的一端,它维护的关系是一指向多
        多对一关联映射:
            咋多的一端加入一个外键指向一的一端,它维护的关系是多指向一
    
      在配置文件中添加:    在一一端使用
    <set><key></key><one-to-many></one-to-many></set>    <key>指定的外键字段必须和<many-to-one>指定的外键字段一致    在多一端使用<many-to-one>
           在有外键的一端设置many-to-one

    数据库中customer表和order表的关系:

    创建实体类:

    public class Customer {
    
        private Integer id;
        private String name;
        private Character gender;
        private Integer age;
        private String level;
    
        //一对多
        private Set<Order> orders = new HashSet<Order>();
        
        public Customer() {
            super();
            
        }

      getters and setters }
    public class Order {
    
        private Integer id;
        private String orderno;
        private String productName;
        
        //多对一
        private Customer customer;
    
        public Order() {
            super();
            // TODO Auto-generated constructor stub
        }

      getters and setters }

     创建映射文件:

    <hibernate-mapping>
        <class name="com.roxy.hibernate.pojo.Customer" table="t_customer">
        
            <id name="id" column="c_id">
                <generator class="native"></generator>
            </id>
            
            <property name="name" column="c_name" not-null="true"></property>
            <property name="gender" column="c_gender" length="1"></property>
            <property name="age" column="c_age"></property>
            <property name="level" column="c_level" length="20"></property>
            
            <set name="orders">
                <key column="customer_id"></key>
                <one-to-many class="com.roxy.hibernate.pojo.Order"/>
            </set>
        </class>
    </hibernate-mapping>
    <hibernate-mapping package="com.roxy.hibernate.pojo">
    
        <!-- 类和表的映射 -->
        <class name="Order" table="t_order">
            <id name="id" column="id">
                <generator class="native"></generator>
            </id>
            <!-- 其他属性映射 -->
            <property name="orderno" column="orderno" length="20"></property>
            <property name="productName" column="product_name" length="100"></property>
    
            <!-- 多对一 -->
            <many-to-one name="customer" class="Customer" column="customer_id" />
        
        </class>
    </hibernate-mapping>   

     创建配置文件:

            <!-- mapping文件 -->
            <mapping resource="com/roxy/hibernate/pojo/Customer.hbm.xml"/>
            <mapping resource="com/roxy/hibernate/pojo/Order.hbm.xml"/>

     查看并分析SQL语句:

    Hibernate: 
           alter table t_order 
           add constraint FKesy3n2gc3fa0s3trrk3tvyv9a 
           foreign key (customer_id) 
           references t_customer (c_id)

    ----- hibernate首先为t_order和t_customer添加外键关联
    Hibernate: insert into t_customer (c_name, c_gender, c_age, c_level) values (
    ?, ?, ?, ?)

    ----- 向t_customer中插入数据(session.save(cust);)
    Hibernate: insert into t_order (orderno, product_name, customer_id) values (
    ?, ?, ?)

    ----- 向t_order中插入数据(session.save(o1);)
    ----- 此时customer_id为null

    Hibernate: insert into t_order (orderno, product_name, customer_id) values (
    ?, ?, ?)

    -----
    向t_order中插入数据(session.save(o2);)
    ----- 此时customer_id为null

    Hibernate: update t_order set customer_id
    =? where id=?

    -----
    维护两个表之间的关系,hibernate更新t_customer数据
    Hibernate: update t_order set customer_id=? where id=?
    ----- 维护两个表之间的关系,hibernate更新t_customer数据

     多对多级联:

    
        双向一对多关联就是多对多关联
        自动生成一个关联表放置两个表的外键,即联合主键

       <!-- 多对多映射 -->
         <!-- table:中间表名 -->
             <set name="users" table="t_user_role" cascade="save-update">
                 <!-- 当前方在中间表的外键 -->
                 <key column="role_id"/>
                 <!-- column:对方在中间表的外键 -->
                 <many-to-many class="User" column="user_id"/>
             </set>

    数据库中user表和role表的关系:

    创建实体类:

    public class User {
    
        private Integer id;
        private String name;
        
        //关联角色
        private Set<Role> roles = new HashSet<Role>();
    
        public User() {
            super();
            // TODO Auto-generated constructor stub
        }
    }
    public class Role {
    
        private Integer id;
        private String name;
    
        //关联用户
        private Set<User> users = new HashSet<User>();
    
        public Role() {
            super();
            // TODO Auto-generated constructor stub
        }
    }

    创建映射文件:

    User:

    <set name="roles" table="t_user_role" > <!-- 当前方在中间表的外键 --> <key column="user_id"/> <!-- column:对方在中间表的外键 --> <many-to-many class="Role" column="role_id"/> </set>
     Role:

    <set name="users" table="t_user_role" > <!-- 当前方在中间表的外键 --> <key column="role_id"/> <!-- column:对方在中间表的外键 --> <many-to-many class="User" column="user_id"/> </set>

    创建配置文件:

            <mapping resource="com/roxy/hibernate/pojo/User.hbm.xml" />
            <mapping resource="com/roxy/hibernate/pojo/Role.hbm.xml" />

    查看并分析SQL语句:

    Hibernate: 
        insert
        into
            t_user
            (name)
        values
            (?)
    Hibernate:
        insert
        into
            t_role
            (name)
        values
            (?)
    Hibernate:
        insert
        into
            t_user_role
            (user_id, role_id)
        values
            (?, ?)
    Hibernate:
        insert
        into
            t_user_role
            (role_id, user_id)
        values
            (?, ?)

    ----- 虽然在test中只保存了user,但是在两个表的映射文件中都对彼此的关联关系进行维护,体现在SQL语句上就是执行了两次t_user_role的插入操作,这就导致了重复插入,报告联合主键重复的异常

     解决方法:

      1 既然两个表同时维护关联导致异常,那么只要一个表放弃维护即可,使用inverse:

    <set name="users" table="t_user_role" inverse="true">

      2 在一个表中设置关联保存,在执行test的时候只对此表进行save操作:

    <set name="users" table="t_user_role" cascade="save-update">
  • 相关阅读:
    BPM平台在企业业务系统中使用的价值讨论
    零售餐饮行业的信息化建设
    LINQ 与Oracle应用 :转帖
    k2之于.NET流程应用开发者
    利用xslt导出复杂样式的excel,支持多个worksheet
    利用偏移量快速定位数据内容
    简单天气项目中观察者模式解析
    作业3:基于墨刀的:视频剪辑软件原型设计
    必做作业2:视频剪辑软件调研
    .Net Core项目依赖项问题
  • 原文地址:https://www.cnblogs.com/roxy/p/7608778.html
Copyright © 2011-2022 走看看