• 016 多对多关联映射 单向(many-to-many)


    • 一般的设计中,多对多关联映射,需要一个中间表
    • Hibernate会自动生成中间表
    • Hibernate使用many-to-many标签来表示多对多的关联
    • 多对多的关联映射,在实体类中,跟一对多一样,也是用集合来表示的。

    实例场景:

    用户与他的角色(一个用户拥有多个角色,一个角色还可以属于多个用户)

    Role实体类:

    public class Role {
    
        private int id;
        private String name;
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }

    User实体类:

    public class User {
    
        private int id;
    
        private String name;   
    
        private Set roles;//Role对象的集合
    
            public int getId() {
    
            return id;
    
        }
    
        public void setId(int id) {
    
            this.id = id;
    
        }
    
        public String getName() {
    
            return name;
    
        }
    
        public void setName(String name) {
    
            this.name = name;
    
        }
    
        public Set getRoles() {
    
            return roles;
    
        }
    
        public void setRoles(Set roles) {
    
            this.roles = roles;
    
        }
    }

    Role映射文件:

    <hibernate-mapping>
    
        <class name="com.wjt276.hibernate.Role" table="t_role">
    
            <id name="id">
    
                <generator class="native"/>
    
            </id>
    
            <property name="name" column="name"/>
    
        </class>
    
    </hibernate-mapping>

    User映射文件:

    <hibernate-mapping>
    
        <class name="com.wjt276.hibernate.User" table="t_user">
    
            <id name="id" column="id">
    
                <generator class="native"/>
    
            </id>
    
            <property name="name"/>
    
            <!--使用<set>标签映射集合(set),标签中的name值为对象属性名(集合roles),而使用table属性是用于生成第三方表名称,例:table="t_user_role",但是第三方面中的字段是自动加入的,作为外键分别指向其它表。
    
    所以表<key>标签设置,例:<key column="userid"/>,意思是:在第三方表(t_user_role)中加入一个外键并且指向当前的映射实体类所对应的表(t_user).使用<many-to-many>来指定此映射集合所对象的类(实例类),并且使用column属性加入一个外键指向Role实体类所对应的表(t_role) -->
    
            <set name="roles" table="t_user_role">
    
                <key column="userid"/>
    
                <many-to-many class="com.wjt276.hibernate.Role" column="roleid"/>
    
            </set>
    
        </class>
    
    </hibernate-mapping>

    导出至数据库表所生成SQL语句

    create table t_role (id integer not null auto_increment, name varchar(255), primary key (id))

    create table t_user (id integer not null auto_increment, name varchar(255), primary key (id))

    create table t_user_role (userid integer not null, roleid integer not null, primary key (userid, roleid))

    alter table t_user_role add index FK331DEE5F1FB4B2D4 (roleid), add constraint FK331DEE5F1FB4B2D4 foreign key (roleid) references t_role (id)

    alter table t_user_role add index FK331DEE5F250A083E (userid), add constraint FK331DEE5F250A083E foreign key (userid) references t_user (id)

    注:根据DDL语句可以看出第三方表的主键是一个复合主键(primary key (userid, roleid)),也就是说记录不可以有相同的数据。

    数据库表及结构:

    多对多关联映射 单向数据存储:

    session = HibernateUtils.getSession();
    
                tx = session.beginTransaction();
    
    
                Role r1 = new Role();
                r1.setName("数据录入人员");
                session.save(r1);
    
               
                Role r2 = new Role();
                r2.setName("商务主管");
                session.save(r2);
             
                Role r3 = new Role();
                r3.setName("大区经理");
                session.save(r3);
           
                User u1 = new User();
                u1.setName("10");
                Set<Role> u1Roles = new HashSet<Role>();
                u1Roles.add(r1);
                u1Roles.add(r2);
                u1.setRoles(u1Roles);
    
               
    
                User u2 = new User();
               u2.setName("祖儿");
                Set<Role> u2Roles = new HashSet<Role>();
                u2Roles.add(r2);
                u2Roles.add(r3);
                u2.setRoles(u2Roles);
                User u3 = new User();
                u3.setName("成龙");
                Set<Role> u3Roles = new HashSet<Role>();
                u3Roles.add(r1);
                u3Roles.add(r2);
                u3Roles.add(r3);
                u3.setRoles(u3Roles);
    
             
                session.save(u1);
                session.save(u2);
                session.save(u3);
    
               
    
                tx.commit();

    发出SQL语句:

    Hibernate: insert into t_role (name) values (?)

    Hibernate: insert into t_role (name) values (?)

    Hibernate: insert into t_role (name) values (?)

    Hibernate: insert into t_user (name) values (?)

    Hibernate: insert into t_user (name) values (?)

    Hibernate: insert into t_user (name) values (?)

    Hibernate: insert into t_user_role (userid, roleid) values (?, ?)

    Hibernate: insert into t_user_role (userid, roleid) values (?, ?)

    Hibernate: insert into t_user_role (userid, roleid) values (?, ?)

    Hibernate: insert into t_user_role (userid, roleid) values (?, ?)

    Hibernate: insert into t_user_role (userid, roleid) values (?, ?)

    Hibernate: insert into t_user_role (userid, roleid) values (?, ?)

    Hibernate: insert into t_user_role (userid, roleid) values (?, ?)

    注:前三条SQL语句,添加Role记录,第三条到第六条添加User,最后7条SQL语句是在向第三方表(t_user_role)中添加多对多关系(User与Role关系)

    多对多关联映射 单向数据加载:

                session = HibernateUtils.getSession();
    
                tx = session.beginTransaction();
    
               
    
                User user = (User)session.load(User.class, 1);
    
                System.out.println("user.name=" + user.getName());
    
                for (Iterator<Role> iter = user.getRoles().iterator(); iter.hasNext();){
    
                    Role role = (Role) iter.next();
    
                    System.out.println(role.getName());
    
                }
    
                //提交事务
    
                tx.commit();

    Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_ from t_user user0_ where user0_.id=?

    user.name=10

    Hibernate: select roles0_.userid as userid1_, roles0_.roleid as roleid1_, role1_.id as id2_0_, role1_.name as name2_0_ from t_user_role roles0_ left outer join t_role role1_ on roles0_.roleid=role1_.id where roles0_.userid=?

    商务主管

    数据录入人员

  • 相关阅读:
    shell-用户权限操作
    Python 库列表
    【random】模块运用,随机数实例
    Python 原生文件读写
    Python 运用pymysql+pandas 完成连接 MySQL 数据库读
    MySQL命名、设计及使用规范
    测试for循环计算耗时
    正则表达式速查表
    MySQL8.0.21下载安装详细教程
    MySQL 修改目录重置
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4078971.html
Copyright © 2020-2023  润新知