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

实例场景:

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

Role实体类:

  1. public class Role {
  2.  
  3. private int id;
  4. private String name;
  5. public int getId() {
  6. return id;
  7. }
  8.  
  9. public void setId(int id) {
  10. this.id = id;
  11. }
  12.  
  13. public String getName() {
  14. return name;
  15. }
  16.  
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20.  
  21. }

User实体类:

  1. public class User {
  2.  
  3. private int id;
  4.  
  5. private String name;
  6.  
  7. private Set roles;//Role对象的集合
  8.  
  9. public int getId() {
  10.  
  11. return id;
  12.  
  13. }
  14.  
  15. public void setId(int id) {
  16.  
  17. this.id = id;
  18.  
  19. }
  20.  
  21. public String getName() {
  22.  
  23. return name;
  24.  
  25. }
  26.  
  27. public void setName(String name) {
  28.  
  29. this.name = name;
  30.  
  31. }
  32.  
  33. public Set getRoles() {
  34.  
  35. return roles;
  36.  
  37. }
  38.  
  39. public void setRoles(Set roles) {
  40.  
  41. this.roles = roles;
  42.  
  43. }
  44. }

Role映射文件:

  1. <hibernate-mapping>
  2.  
  3. <class name="com.wjt276.hibernate.Role" table="t_role">
  4.  
  5. <id name="id">
  6.  
  7. <generator class="native"/>
  8.  
  9. </id>
  10.  
  11. <property name="name" column="name"/>
  12.  
  13. </class>
  14.  
  15. </hibernate-mapping>

User映射文件:

  1. <hibernate-mapping>
  2.  
  3. <class name="com.wjt276.hibernate.User" table="t_user">
  4.  
  5. <id name="id" column="id">
  6.  
  7. <generator class="native"/>
  8.  
  9. </id>
  10.  
  11. <property name="name"/>
  12.  
  13. <!--使用<set>标签映射集合(set),标签中的name值为对象属性名(集合roles),而使用table属性是用于生成第三方表名称,例:table="t_user_role",但是第三方面中的字段是自动加入的,作为外键分别指向其它表。
  14.  
  15. 所以表<key>标签设置,例:<key column="userid"/>,意思是:在第三方表(t_user_role)中加入一个外键并且指向当前的映射实体类所对应的表(t_user).使用<many-to-many>来指定此映射集合所对象的类(实例类),并且使用column属性加入一个外键指向Role实体类所对应的表(t_role) -->
  16.  
  17. <set name="roles" table="t_user_role">
  18.  
  19. <key column="userid"/>
  20.  
  21. <many-to-many class="com.wjt276.hibernate.Role" column="roleid"/>
  22.  
  23. </set>
  24.  
  25. </class>
  26.  
  27. </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)),也就是说记录不可以有相同的数据。

数据库表及结构:

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

  1. session = HibernateUtils.getSession();
  2.  
  3. tx = session.beginTransaction();
  4.  
  5. Role r1 = new Role();
  6. r1.setName("数据录入人员");
  7. session.save(r1);
  8.  
  9. Role r2 = new Role();
  10. r2.setName("商务主管");
  11. session.save(r2);
  12.  
  13. Role r3 = new Role();
  14. r3.setName("大区经理");
  15. session.save(r3);
  16.  
  17. User u1 = new User();
  18. u1.setName("10");
  19. Set<Role> u1Roles = new HashSet<Role>();
  20. u1Roles.add(r1);
  21. u1Roles.add(r2);
  22. u1.setRoles(u1Roles);
  23.  
  24. User u2 = new User();
  25. u2.setName("祖儿");
  26. Set<Role> u2Roles = new HashSet<Role>();
  27. u2Roles.add(r2);
  28. u2Roles.add(r3);
  29. u2.setRoles(u2Roles);
  30. User u3 = new User();
  31. u3.setName("成龙");
  32. Set<Role> u3Roles = new HashSet<Role>();
  33. u3Roles.add(r1);
  34. u3Roles.add(r2);
  35. u3Roles.add(r3);
  36. u3.setRoles(u3Roles);
  37.  
  38. session.save(u1);
  39. session.save(u2);
  40. session.save(u3);
  41.  
  42. 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关系)

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

  1. session = HibernateUtils.getSession();
  2.  
  3. tx = session.beginTransaction();
  4.  
  5. User user = (User)session.load(User.class, 1);
  6.  
  7. System.out.println("user.name=" + user.getName());
  8.  
  9. for (Iterator<Role> iter = user.getRoles().iterator(); iter.hasNext();){
  10.  
  11. Role role = (Role) iter.next();
  12.  
  13. System.out.println(role.getName());
  14.  
  15. }
  16.  
  17. //提交事务
  18.  
  19. 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=?

商务主管

数据录入人员

016 多对多关联映射 单向(many-to-many)的更多相关文章

  1. java之hibernate之单向的多对多关联映射

    这篇 单向的多对多关联映射 1.如何在权限管理中,角色和权限之间的关系就是多对多的关系,表结构为: 2.类结构 Permission.java public class Permission impl ...

  2. (Hibernate进阶)Hibernate映射——多对多关联映射(八)

    多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接开始. 映射原理 不论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张做一个关联.用第三张表来解决可能会造成数 ...

  3. Hibernate(六)——多对多关联映射

    前面几篇文章已经较讲解了三大种关联映射,多对多映射就非常简单了,不过出于对关联映射完整性的考虑,本文还是会简要介绍下多对多关联映射. 1.单向多对多关联映射 情景:一个用户可以有多个角色,比如数据录入 ...

  4. 017 多对多关联映射 双向(many-to-many)

    多对多关联映射 双向 两方都持有对象引用,修改对象模型,但数据的存储没有变化. 再修改映射文件: public class Role { private int id; private String ...

  5. 014 一对多关联映射 单向(one-to-many)

    在对象模型中,一对多的关联关系,使用集合来表示. 实例场景:班级对学生:Classes(班级)和Student(学生)之间是一对多的关系. 多对一.一对多的区别: 多对一关联映射:在多的端加入一个外键 ...

  6. 一口一口吃掉Hibernate(六)——多对多关联映射

    今天来说说hibernate中的多对多关联映射,多对多关联映射涉及到单向映射和双向映射2种. 首先举个多对多关联例子:用户User和角色Role,一个用户可以属于多个角色,一个角色可以有多个用户.这就 ...

  7. 【SSH系列】Hibernate映射 -- 多对多关联映射

         映射原理 在数据库学习阶段,我们知道,如果实体和实体之间的关系是多对多,那么我们就抽出来第三张表,第一张表和第二张表的主键作为第三表的联合主键,结合我们的hibernate,多对多关联,无论 ...

  8. 【SSH进阶之路】Hibernate映射——多对多关联映射(八)

    上篇博文[SSH进阶之路]Hibernate映射——一对多关联映射(七),我们介绍了一对多关联映射,它是多对多关联映射的基础. 多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接 ...

  9. Hibernate的关联映射——单向1-N关联

    Hibernate的关联映射--单向1-N关联 单向1-N关联的持久化类里需要使用集合属性.因为1的一端需要访问N的一端,而N的一端将以集合(Set)形式表现.从这个意义上来看,1-N(实际上还包括N ...

随机推荐

  1. AVL树的旋转操作详解

    [0]README 0.0) 本文部分idea 转自:http://blog.csdn.net/collonn/article/details/20128205 0.1) 本文仅针对性地分析AVL树的 ...

  2. 全栈必备 JavaScript基础

    1995年,诞生了JavaScript语言,那一年,我刚刚从大学毕业.在今年RedMonk 推出的2017 年第一季度编程语言排行榜中,JavaScript 排第一,Java 第二,Python 反超 ...

  3. shiro基础学习(四)—shiro与项目整合

    一.认证 1.配置web.xml   2.配置applicationContext.xml      在applicationContext.xml中配置一个bean,ID和上面的过滤器的名称一致. ...

  4. Activity的切换动画

    Activity在切换或者退出的时候可以自定义动画的,比如AlphaAnimation.TranslateAnimation.ScaleAnimation等自定义的动画.我们在Activity启动的时 ...

  5. 数字图像处理(MATLAB版)学习笔记(2)——第2章 灰度变换与空间滤波

    0.小叙闲言 1.本章整体结构 2.书中例子 例2.1 主要是使用函数imadjust,来熟悉一下灰度处理,体验一把 >> imread('myimage.jpg'); >> ...

  6. C#委托冒泡

    委托的实现,就是编译器自行定义了一个类:有三个重要参数1.制定操作对象,2.指定委托方法3.委托链 看如下一个列子: class DelegatePratice { public static voi ...

  7. 网络语音视频技术浅议(附多个demo源码下载)

    我们在开发实践中常常会涉及到网络语音视频技术.诸如即时通讯.视频会议.远程医疗.远程教育.网络监控等等,这些网络多媒体应用系统都离不开网络语音视频技术.本人才疏学浅,对于网络语音视频技术也仅仅是略知皮 ...

  8. java多线程基本概述(三)——同步块

    1.1.synchronized方法的弊端 package commonutils; public class CommonUtils { public static long beginTime1; ...

  9. 浅谈C#抽象类

    抽象类 先说个事,一个类实例化为一个实例.就是一只狗,实例化一下,就成了一只哈士奇(具体的二哈).但是,一个动物类实例化呐,成了啥? 压根就不能实例化.这,就是抽象类的概念引入. 概念:C#允许把类和 ...

  10. 在线恶意软件和URL分析集成框架 – MalSub

    malsub是一个基于Python 3.6.x的框架,它的设计遵循了当前最流行的互联网软件架构RESTful架构,并通过其RESTful API应用程序编程接口(API),封装了多个在线恶意软件和UR ...