hibernate一对多和多对多表关系

一对多

  • 表中的表达

          在多的一方使用外键指向一的一方的主键。

  • 实体对象中的表达

       在一的一方中使用集合表达其持有多个多的一方,

       在多的一方中使用对象引用一的一方,表达多的一方属于哪个一的一方。

  

  • 配置文件中的相关配置

        1.一的一方的配置文件

       在一的一方中使用的集合为set,所以这里使用set标签,name属性是集合的属性名,column属性是外键列名,class属性是多的一方的完整类名。如果在class属性中设置了package属性则这里可使用普通类名。

<set name="linkMens">
         <key column="lkm_cust_id"></key>
          <one-to-many class="LinkMan" />
</set>

  2.多的一方的配置文件

    多的一方中的属性个数与一的一方的属性个数相同,name为引用属性名,column属性为外键列名,class属性为一的一方的对象的完整类名。

<many-to-one name="customer" column="lkm_cust_id" class="Customer">
</many-to-one>
  •  在Java代码中操作关联的属性

 

级联操作cascade

  • 在一的一方中使用cascade属性可以进行级联操作,此属性有三种选项:
  • save-update:级联保存更新
  • delete:级联删除
  • all:级联保存更新+级联删除

关系维护反转inverse属性

  •    inverse="false":反转为false,即为自己维护关系也就是外键
  •    inverse="true":   反转为true,即对方维护关系

注意,当配置中一的一方的inverse属性配置为true,即对方维护外键,且cascade属性未设置为级联删除时,在进行删除操作时只删除一的一方是删不掉的,在进行删除时有两种方式:

1.自己维护外键关系,在删除一的一方时,将多的一方的外键置为null

2.对方维护外键关系,但是一的一方设置cascade属性为级联删除,在一的一方进行删除时同时将多的一方进行删除。

 

多对多关系的表达

  两方都是用集合来表达拥有多个对方

 

实体类映射关系

public class User {
    
    private Long user_id;
    private String user_code;
    private String user_name;
    private String user_password;
    private Character user_state;
    //表达多对多
    private Set<Role> roles = new HashSet<Role>();
        
}

一个user对应多个role

1 public class Role {    
2     private Long role_id;
3     private String role_name;
4     private String role_memo;
5     //表达多对多
6     private Set<User> users = new HashSet<User>();
7 }


配置文件映射关系

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping package="cn.itcast.domain" >
 6     <class name="User" table="sys_user" >
 7         <id name="user_id"  >
 8             <generator class="native"></generator>
 9         </id>
10         <property name="user_code"  ></property>
11         <property name="user_name"  ></property>
12         <property name="user_password"  ></property>
13         <property name="user_state"  ></property>
14     
15         <!-- 多对多关系表达 -->
16         <!-- 
17             name: 集合属性名
18             table: 配置中间表名
19             key
20              |-column:外键,别人引用"我"的外键列名
21              class: 我与哪个类是多对多关系
22              column:外键.我引用比人的外键列名
23          -->
24         
25         <set name="roles" table="sys_user_role" cascade="save-update" >
26             <key column="user_id" ></key>
27             <many-to-many class="Role" column="role_id" ></many-to-many>
28         </set>
29     
30     </class>
31 </hibernate-mapping>
 1 <hibernate-mapping package="cn.itcast.domain" >
 2     <class name="Role" table="sys_role" >
 3         <id name="role_id"  >
 4             <generator class="native"></generator>
 5         </id>
 6         <property name="role_name"  ></property>
 7         <property name="role_memo"  ></property>
 8 
 9     <!-- 使用inverse属性
10             true: 放弃维护外键关系
11             false(默认值):维护关系
12              -->        
13         <set name="users" table="sys_user_role" inverse="true" >
14             <key column="role_id" ></key>
15             <many-to-many class="User" column="user_id" ></many-to-many>
16         </set>
17     </class>
18 </hibernate-mapping>


 

name table column class 等属性含义和上面相同。

 

关系维护

  • 一对多的关系维护是通过修改外键来完成的,
  • 多对多的关系维护是通过在关系表中插入记录实现的。

 在多对多关系中如果两方都维护关系则关系表中的同一条记录会被插入两次,违反id唯一性,所以需要有一方放弃维护关系。

在将来的开发中,如果遇到多对多关系,一定要选择一的一方放弃维护关系。一般谁来放弃要看业务方向,例如录入员工时,需要为员工指定所属角色,那么业务方向就是由员工维护角色,角色不需要维护与员工关系,角色放弃维护。

 

多对多操作

新加一对关系,例如一个User新加一个role的时候主要分为四步,主要思想即为将所有对象转换为持久化状态。

 1 public void fun3(){
 2         //1 获得session
 3         Session session = HibernateUtils.openSession();
 4         //2 开启事务
 5         Transaction tx = session.beginTransaction();
 6         //-------------------------------------------------
 7         //3操作
 8         //1> 获得用户
 9         User user = session.get(User.class, 1l);
10         //2> 创建角色
11         Role r = new Role();
12         r.setRole_name("总经理");
13         //3> 将角色添加到用户中
14         user.getRoles().add(r);
15         //4> 将角色转换为持久化
16         session.save(r);
17         //-------------------------------------------------
18         //4提交事务
19         tx.commit();
20         //5关闭资源
21         session.close();
22     }

 如果user和role设置为了级联保存,则事务提交的时候,保存user的时候也会级联保存role,不用再手动调用session.save()保存role。

posted @ 2018-01-02 23:08  Garcia11  阅读(1779)  评论(0)    收藏  举报