SSH与SSM学习之hibernate20——多对多操作

SSH与SSM学习之hibernate20——多对多操作

一、说明

关于多对多的关系可以查看 SSH与SSM学习之hibernate16——表与表的三种关系

这里我们涉及到的是 用户(员工)与角色之间的多对多的关系。


二、 用户(员工)实体

2.1 User.java

**
 * @author:qiwenming
 * @date:2017/9/19 0019   20:57
 * @description:
 * 用户类
 */
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<>();

    ....省略了get/set方法...
}

2.2 User.hbm.xml

<?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.qwm.hibernate03.domain" >
    <class name="User" table="sys_user" >
        <id name="user_id"  >
            <generator class="native"></generator>
        </id>
        <property name="user_code"  ></property>
        <property name="user_name"  ></property>
        <property name="user_password"  ></property>
        <property name="user_state"  ></property>
        <!-- 多对多关系表达 -->
        <!--
            name: 集合属性名
            table: 配置中间表名
            key
             |-column:外键,别人引用"我"的外键列名
             class: 我与哪个类是多对多关系
             column:外键.我引用比人的外键列名
         -->
        <set name="roles" table="sys_user_role">
            <!---->
            <key column="user_id"></key>
            <many-to-many class="Role" column="role_id"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

三、角色实体

3.1 Role.java

public class Role {
    private Long role_id;
    private String role_name;
    private String role_memo;

    //表达多对对关系
    private Set<User> users = new HashSet<>();    

    ....省略了get/set方法...
}

3.2 Role.hbm.xml

<?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.qwm.hibernate03.domain" >
    <class name="Role" table="sys_role" >
        <id name="role_id"  >
            <generator class="native"></generator>
        </id>
        <property name="role_name"  ></property>
        <property name="role_memo"  ></property>

        <!-- 多对多关系表达 -->
        <!--
            name: 集合属性名
            table: 配置中间表名
            key
             |-column:外键,别人引用"我"的外键列名
             class: 我与哪个类是多对多关系
             column:外键.我引用比人的外键列名
         -->
        <set name="users" table="sys_user_role" inverse="true">
            <key column="role_id"></key>
            <many-to-many class="User" column="user_id"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

四、保存用户以及角色

4.1 产生的问题以及解决

注意: 这里我们保存用户与角色的数据的时候,需要注意,二者默认都是维护着关系的,就会导致二者都会相互之间添加到维护他们两者之间关系的表中,这样就会产生主键冲突,导致无法数据添加失败。

解决方式有两种:

第一种 我们在添加数据关系的时候,只添加一方的关系,不添添加另一方的关系

如:

    //3.3表达关系
    user1.getRoles().add(role1);
    user1.getRoles().add(role2);
    user2.getRoles().add(role1);
    user2.getRoles().add(role2);

//  role1.getUsers().add(user1);
//  role1.getUsers().add(user2);
//  role2.getUsers().add(user1);
//  role2.getUsers().add(user2);

或者

        //3.3表达关系
//  user1.getRoles().add(role1);
//  user1.getRoles().add(role2);
//  user2.getRoles().add(role1);
//  user2.getRoles().add(role2);

    role1.getUsers().add(user1);
    role1.getUsers().add(user2);
    role2.getUsers().add(user1);
    role2.getUsers().add(user2);

第二种 这种方式就是配置一方放弃维护关系,可以配置到 User 中,也可以配置到 Role中,

如果是 Role.hbm.xml

....
<set name="users" table="sys_user_role" inverse="true">
    <key column="role_id"></key>
    <many-to-many class="User" column="user_id"></many-to-many>
</set>
...

或者

如果是 User.hbm.xml

......
<set name="roles" table="sys_user_role" inverse="true">
    <!---->
    <key column="user_id"></key>
    <many-to-many class="Role" column="role_id"></many-to-many>
</set>
......

下面的例子中,我们采用的是配置文件中 Role放弃维护关系,就是上面我们的完整配置

4.2 代码实例


/**
 * 保存用户以及角色
 */
@Test
public void test1(){
    //1.创建session
    Session session = HibernateUtils.openSession();
    //2.开启事务
    Transaction t = session.beginTransaction();
    //===================================
    //3.操作
    //3.1创建两个用户
    User user1 = new User();
    user1.setUser_name("高晓明");
    User user2 = new User();
    user2.setUser_name("李志锋")
    ;
    //3.2创建两角色
    Role role1 = new Role();
    role1.setRole_name("保安");
    Role role2 = new Role();
    role2.setRole_name("清洁工");

    //3.3表达关系
    user1.getRoles().add(role1);
    user1.getRoles().add(role2);
    user2.getRoles().add(role1);
    user2.getRoles().add(role2);

    role1.getUsers().add(user1);
    role1.getUsers().add(user2);
    role2.getUsers().add(user1);
    role2.getUsers().add(user2);

    //3.4数据持久化
    session.save(user1);
    session.save(user2);
    session.save(role1);
    session.save(role2);

    //===================================

    //4.提交事务
    t.commit();
    //5.关闭资源
    session.close();
}

4.3 结果

用户表

这里写图片描述

角色表

这里写图片描述

用户-角色表

这里写图片描述


五、为用户添加角色

5.1 问题说明

我们为用户保存角色的时候,有两种方式处理

第一种:我们自己保存角色

例如

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

第二种:再我们的user.hbm.xml中配置级联保存

例如

<set name="roles" table="sys_user_role" cascade="save-update">
    <!---->
    <key column="user_id"></key>
    <many-to-many class="Role" column="role_id"></many-to-many>
</set>

这里我们使用的是第一种方式

5.2 示例代码

/**
 * 为用户添加角色
 * 我们来实现为 “高晓峰”添加一个“部门经理”的角色
 */
@Test
public void test2(){
    //1.创建session
    Session session = HibernateUtils.openSession();
    //2.开启事务
    Transaction t = session.beginTransaction();
    //===================================
    //3.操作
    //3.1 得到高晓峰这个用户
    User user = session.get(User.class,1L);
    //3.2 创建“部门经理”这个角色
    Role role = new Role();
    role.setRole_name("部门经理");
    //3.3 给高晓峰添加“部门经理”这个角色
    //这里不用调用保存的方法,保存user,因为user是持久化对象
    user.getRoles().add(role);
//        session.save(role);

    //===================================

    //4.提交事务
    t.commit();
    //5.关闭资源
    session.close();
}

5.3 结果

这里写图片描述


六、为用户删除角色

6.1 示例代码

/**
 * 为用户删除角色
 * 我们来实现为 “高晓峰”删除“清洁工”和“保安”的角色
 */
@Test
public void test3(){
    //1.创建session
    Session session = HibernateUtils.openSession();
    //2.开启事务
    Transaction t = session.beginTransaction();
    //===================================
    //3.操作
    //3.1获取到用户
    //3.2获取到“清洁工”这个角色
    //3.3获取到“保安”这个角色
    //3.4从用户的角色集合中删除“保安”和“清洁工”
    User user = session.get(User.class,1L);
    Role role1 = session.get(Role.class,1L);
    Role role2 = session.get(Role.class,2L);
    //user是持久化对象那个,所以不用调用保存的方法
    user.getRoles().remove(role1);
    user.getRoles().remove(role2);
    //===================================

    //4.提交事务
    t.commit();
    //5.关闭资源
    session.close();
}

6.2 结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值