Hibernate多对多关系配置

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/weixin_43014205/article/details/86078204

需求:一个用户可以有多个角色,一个角色也可以被多个用户选择

POJO:

public class User {
    private Long user_id;
    private String user_code;
    private String user_name;
    private String user_password;
    private String user_state;
    //一个用户选择多个角色
    private Set<Role> roles = new HashSet<>();
}
public class Role {
    private Long role_id;
    private String role_name;
    private String role_memo;
    private Set<User> users = new HashSet<>();
}

对应的数据库表:user

CREATE TABLE `user` (
  `user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `user_code` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户账号',
  `user_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户名称',
  `user_password` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户密码',
  `user_state` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '1:正常,0:暂停',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

 role

CREATE TABLE `role` (
  `role_id` bigint(32) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '角色名称',
  `role_memo` varchar(128) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

中间表:user_role

CREATE TABLE `user_role` (
  `role_id` bigint(20) NOT NULL,
  `user_id` bigint(20) NOT NULL,
  PRIMARY KEY (`role_id`,`user_id`),
  KEY `user_id` (`user_id`),
  CONSTRAINT `user_role_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `role` (`role_id`),
  CONSTRAINT `user_role_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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>
    <class name="com.bullet.domain.User" table="user">
        <!--建立类中的属性与表中的主键对应-->
        <id name="user_id" column="user_id" >
            <generator class="native"/>
        </id>
        <!--建立类中的普通的属性和表的字段的对应-->
        <property name="user_code" column="user_code" />
        <property name="user_name" column="user_name"/>
        <property name="user_password" column="user_password"/>
        <property name="user_state" column="user_state"/>

           <!--配置多对多-->
        <!--set:name  当前集合的名称   table  :多对多的中间表表名>
             <key column  当前表的外键
             <many-to-many class="" column=""/>
             class:集合中对象的全路径
             column:集合中对象的外键
         -->
        <set name="roles" table="user_role" cascade="save-update">
            <key column="user_id"></key>
            <many-to-many class="com.bullet.domain.Role" column="role_id"/>
        </set>

    </class>
</hibernate-mapping>

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>
    <class name="com.bullet.domain.Role" table="role">
        <!--建立类中的属性与表中的主键对应-->
        <id name="role_id" column="role_id" >
            <generator class="native"/>
        </id>
        <!--建立类中的普通的属性和表的字段的对应-->
        <property name="role_name" column="role_name" />
        <property name="role_memo" column="role_memo"/>

       <!--配置多对多-->
        <!--set:name  当前集合的名称   table  :多对多的中间表表名>
            <key column  当前表的外键
            <many-to-many class="" column=""/>
            class:集合中对象的全路径
            column:集合中对象的外键
        -->
        <set name="users" table="user_role" inverse="true">
            <key column="role_id"></key>
            <many-to-many class="com.bullet.domain.User" column="user_id"/>
        </set>

    </class>
</hibernate-mapping>

多对多的操作和一对多的操作几乎完全一致

(1)在配置关系时可以单向配置 ,也可以双向配置

唯一不同的是,多对多的双向配置一定要让一方放弃外键的维护权,否则会报错,原因是联系两张表的第三张表关系表,不能出现两条相同的记录。而一对多时双向配置可以双方都不放弃外键维护权,建议让一方放弃外键维护权是为了性能着想。

(2)保存时和一对多一样,可以双向保存,也可以单向保存,前提是单向保存时一定要设置级联保存

  保存谁就在谁的配置文件中设置级联保存

(3)多对多的操作实质上是对集合的操作             注意:持久化对象设置属性会自动保存   

需求:给用户1添加角色3

  public void test2(){
        //关系操作   实质是操作集合
        /**
         * 需求:给用户1添加角色3
         */
        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();
        //拿出角色和用户
        User user1 = currentSession.get(User.class, 9L);
        Role role3 = currentSession.get(Role.class, 8L);
        //添加关系
        user1.getRoles().add(role3);
        role3.getUsers().add(user1);
        //持久态对象设置属性可以直接自动保存


        transaction.commit();
        currentSession.close();
    }

需求:把用户2的角色3换成角色1

 public void test3(){
        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();
        //把用户2的角色3改为角色1
        User user2 = currentSession.get(User.class, 10L);
        Role role3 = currentSession.get(Role.class, 8L);
        Role role1 = currentSession.get(Role.class, 6L);

        //删除用户2的角色3
        user2.getRoles().remove(role3);
        //给用户2添加角色1        持久化对象自动保存
        user2.getRoles().add(role1);


        transaction.commit();
        currentSession.close();
    }

猜你喜欢

转载自blog.csdn.net/weixin_43014205/article/details/86078204