hibernate中的关系映射03多对多映射

需求:用户与角色是多对多的关系

一、模型设计

1、设计表(用hibernate自动生成表)
用户表
角色表
用户角色表


2、创建User实体类
package com.**.hibernate.pojo.many2many;
import java.util.HashSet;
import java.util.Set;
/**
 * 用户(多方)
 */
public class User{
    private Integer id;
    private String name;
    //关联角色
    private Set<Role> roles = new HashSet<Role>();
}

注:一般在开发中配置多方时用的都是set集合,在Mapping配置文件时,配置节点为<set>,

因为List允许重复的值,所以一般不用,感兴趣的可以自己实验一下,只需要把Mapping配置文件中

把<set>节点变成<list>节点即可(标签内的子标签有差别,注意不要直接把set变成list)

3、创建Role实体类

package com.**.hibernate.pojo.many2many;
import  java.util.HashSet;
import java.util.Set;
/**
 * 角色(多方)
 */
public class Role{
    private Integer id;
    private String name;
    //关联用户
    private Set<User> users = new HashSet<User>();
}

4、User配置
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping package="com.**.hibernate.pojo.many2many">
 
     <class name="User" table="t_user">
         <id name="id" column="id">
             <generator class="native"></generator>
         </id>
         <property name="name" column="name"></property>
         
         <!-- 多对多映射 -->
         <!-- 
             table:中间表名
          -->
         <set name="roles" table="t_user_role">
             <!-- 当前方在中间表的外键 -->
             <key column="user_id"/>
             <!-- column:对方在中间表的外键 -->
             <many-to-many class="Role" column="role_id"/>
         </set>
     </class>
 
</hibernate-mapping>   

5、Role配置
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping package="com.**.hibernate.pojo.many2many">
 
     <class name="Role" table="t_role">
         <id name="id" column="id">
             <generator class="native"></generator>
         </id>
         <property name="name" column="name"></property>
         
         <!-- 多对多映射 -->
         <!-- 
             table:中间表名
          -->
         <set name="users" table="t_user_role">
             <!-- 当前方在中间表的外键 -->
             <key column="role_id"/>
             <!-- column:对方在中间表的外键 -->
             <many-to-many class="User" column="user_id"/>
         </set>
     </class>
 
</hibernate-mapping>   

6、将映射文件加入hibernte.cfg.xml
<mapping resource="com/**/hibernate/pojo/many2many/User.hbm.xml"/>
<mapping resource="com/**/hibernate/pojo/many2many/Role.hbm.xml"/>

二、测试增加

1、inverse
注意:如果不设置 inverse选项,那么执行以下测试会报告错误: Duplicate entry '1-1' for key 'PRIMARY'
查看控制台发现,多出一条sql语句: insert  into  t_user_role ...
因为User 和 Role 都同时维护了 中间表,导致插入数据联合主键重复,
因此可以在Role配置文件的 set 节点中设置 inverse="true"
<set name="users" table="t_user_role" inverse="true">
public class  Many2ManyTest {
    /**
     * 需求:建立1个用户,1个角色
     */
    @Test
    public void testCreateUserAndRole(){

        User user = new User();
        user.setName("奥特曼");
        Role role = new Role();
        role.setName("超级管理员");

        //建立双向关系
        user.getRoles().add(role);
        role.getUsers().add(user);

        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();

        session.save(user);
        session.save(role);

        tx.commit();
        session.close();
    }
}


三、级联保存

1、在User配置文件中配置级联保存
<set name="roles" table="t_user_role" cascade="save-update">

2、建立双项关联,只保存user
在设置了inverse的情况下,必须建立双向关联,否则关系表中的数据无法添加
//建立双向关系
user.getRoles().add(role);
role.getUsers().add(user);

Session session = HibernateUtil.openSession();
Transaction tx = session.beginTransaction();

session.save(user);
//session.save(role);

四、级联删除

(1) 如果 不设置级联删除,则只删除用户记录和关联表记录,不会删除角色记录
    /**
     * 级联删除操作
     */
    @Test
    public void testCascadeDelete(){
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();
        
        User u = session.get(User.class, 3);
        session.delete(u);
        
        tx.commit();
        session.close();
    }

(2) 如果设置级联删除,除了删除 用户记录和关联表记录,还会删除角色记录!
在实际开发中,在多对多的关系中不要使用级联删除!!!
<set name="roles" table="t_user_role" cascade="save-update,delete">






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值