欢迎关注我的Github Pages: http://chendu.github.io/

Hibernate多对多(many-to-many):在操作和性能方面都不太理想,所以多对多的关系使用的比较少,实际使用最好转换成一对多的对象模型,实际上Hibernate可以帮我们创建中间关联表,转换成两个一对多的关系.

比如老师和学生是比较常见的多对多关系,我们可以创建一个中间表,用中间表去记录老师和学生之间多对多的关系.

Teacher.java

@Entity
@Table(name = "TB_TEACHER")
public class Teacher {private int teacherId;private String teacherName;private Set<Student> students = new HashSet<Student>();public Teacher(){}public Teacher(String teacherName){this.teacherName = teacherName;}@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "TEACHER_ID", unique = true, nullable = false)public int getTeacherId() {return teacherId;}public void setTeacherId(int teacherId) {this.teacherId = teacherId;}@Column(name = "TEACHER_NAME")public String getTeacherName() {return teacherName;}public void setTeacherName(String teacherName) {this.teacherName = teacherName;}@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)@JoinTable(name = "TB_TEACHER_STUDENT", joinColumns = {@JoinColumn(name = "TEACHER_ID", nullable = false, updatable = false) }, inverseJoinColumns = {@JoinColumn(name = "STUDENT_ID", nullable = false, updatable = false) })public Set<Student> getStudents() {return students;}public void setStudents(Set<Student> students) {this.students = students;}}

Student.java

@Entity
@Table(name = "TB_STUDENT")
public class Student {private int studentId;private String studentName;private Set<Teacher> teachers = new HashSet<Teacher>();public Student(){}public Student(String studentName){this.studentName = studentName;}@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "STUDENT_ID", unique = true, nullable = false)public int getStudentId() {return studentId;}public void setStudentId(int studentId) {this.studentId = studentId;}@Column(name = "STUDENT_NAME")public String getStudentName() {return studentName;}public void setStudentName(String studentName) {this.studentName = studentName;}@ManyToMany(fetch = FetchType.LAZY, mappedBy = "students")public Set<Teacher> getTeachers() {return teachers;}public void setTeachers(Set<Teacher> teachers) {this.teachers = teachers;}}

通过设置Hibernate自动生成代码

hibernate.show_sql = true
hibernate.format_sql = true
hibernate.hbm2ddl.auto = create

自动生成的DDL SQL语句

CREATE TABLE `tb_teacher` (`TEACHER_ID` INT(11) NOT NULL AUTO_INCREMENT,`TEACHER_NAME` VARCHAR(255) NULL DEFAULT NULL,PRIMARY KEY (`TEACHER_ID`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;CREATE TABLE `tb_student` (`STUDENT_ID` INT(11) NOT NULL AUTO_INCREMENT,`STUDENT_NAME` VARCHAR(255) NULL DEFAULT NULL,PRIMARY KEY (`STUDENT_ID`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;CREATE TABLE `tb_teacher_student` (`TEACHER_ID` INT(11) NOT NULL,`STUDENT_ID` INT(11) NOT NULL,PRIMARY KEY (`TEACHER_ID`, `STUDENT_ID`),INDEX `FK_9484qoyn1n7mq08lbv4q2wni0` (`STUDENT_ID`),CONSTRAINT `FK_9484qoyn1n7mq08lbv4q2wni0` FOREIGN KEY (`STUDENT_ID`) REFERENCES `tb_student` (`STUDENT_ID`),CONSTRAINT `FK_l1jwjq45c5vucjgivby1e41a5` FOREIGN KEY (`TEACHER_ID`) REFERENCES `tb_teacher` (`TEACHER_ID`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

A. 测试插入操作:

Teacher teacher1 = new Teacher("teacher1");
Teacher teacher2 = new Teacher("teacher2");
Student student1 = new Student("student1");
Student student2 = new Student("student2");student1.getTeachers().add(teacher1);
student1.getTeachers().add(teacher2);
student2.getTeachers().add(teacher1);session.save(teacher1);
session.save(teacher2);
session.save(student1);
session.save(student2);

用上面的语句执行插入操作,后台console打印出来的SQL:

Hibernate: insert intoTB_TEACHER(TEACHER_NAME) values(?)
Hibernate: insert intoTB_TEACHER(TEACHER_NAME) values(?)
Hibernate: insert intoTB_STUDENT(STUDENT_NAME) values(?)
Hibernate: insert intoTB_STUDENT(STUDENT_NAME) values(?)

数据库中数据

TB_STUDENT

STUDENT_ID STUDENT_NAME
1 student1
2 student2

TB_TEACHER

TEACHER_ID TEACHER_NAME
1 teacher1
2 teacher2

TB_TEACHER_STUDENT (NULL)

B.测试插入操作:

Teacher teacher1 = new Teacher("teacher1");
Teacher teacher2 = new Teacher("teacher2");
Student student1 = new Student("student1");
Student student2 = new Student("student2");teacher1.getStudents().add(student1);
teacher1.getStudents().add(student2);
teacher2.getStudents().add(student1);session.save(teacher1);
session.save(teacher2);
session.save(student1);
session.save(student2);

用上面的语句执行插入操作,后台console打印出来的SQL:

Hibernate: insert intoTB_TEACHER(TEACHER_NAME) values(?)
Hibernate: insert intoTB_STUDENT(STUDENT_NAME) values(?)
Hibernate: insert intoTB_STUDENT(STUDENT_NAME) values(?)
Hibernate: insert intoTB_TEACHER(TEACHER_NAME) values(?)
Hibernate: insert intoTB_TEACHER_STUDENT(TEACHER_ID, STUDENT_ID) values(?, ?)
Hibernate: insert intoTB_TEACHER_STUDENT(TEACHER_ID, STUDENT_ID) values(?, ?)
Hibernate: insert intoTB_TEACHER_STUDENT(TEACHER_ID, STUDENT_ID) values(?, ?)

数据库中数据

TB_STUDENT

STUDENT_ID STUDENT_NAME
1 student1
2 student2

TB_TEACHER

TEACHER_ID TEACHER_NAME
1 teacher1
2 teacher2

TB_TEACHER_STUDENT

TEACHER_ID STUDENT_ID
1 1
1 2
2 1

A 和 B操作的唯一区别是

//A
student1.getTeachers().add(teacher1);
student1.getTeachers().add(teacher2);
student2.getTeachers().add(teacher1);//B
teacher1.getStudents().add(student1);
teacher1.getStudents().add(student2);
teacher2.getStudents().add(student1);

需要注意的是Student.java, @ManyToMany的属性mappedBy = "students"

@Entity
@Table(name = "TB_STUDENT")
public class Student {...@ManyToMany(fetch = FetchType.LAZY, mappedBy = "students")public Set<Teacher> getTeachers() {return teachers;}...
}

当配置了这句话的时候就不可以再配置@JoinTable和@JoinColumn等,同时Teacher就是owning side, Student就是non-owning side,就是Teacher和Student之间的关系是通过Teacher端来维护的.

转载于:https://my.oschina.net/vivine/blog/688070

Hibernate many-to-many相关推荐

  1. java面试常见问题之Hibernate总结

    1  Hibernate的检索方式 Ø  导航对象图检索(根据已经加载的对象,导航到其他对象.) Ø  OID检索(按照对象的OID来检索对象.) Ø  HQL检索(使用面向对象的HQL查询语言.) ...

  2. Spring中启用Hibernate二级缓存步骤

    1.在applicationContext.xml配置文件中SessionFactory  bean中配置缓存 <!-- 配置会话工厂对象 --> <bean id="se ...

  3. ssh(Struts+spring+Hibernate)三大框架整合-简述

    ssh(Struts+spring+Hibernate)三大框架配合使用来开发项目,是目前javaee最流行的开发方式,必须掌握: 注意: 为了稳健起见,每加入一个框架,我们就需要测试一下,必须通过才 ...

  4. Hibernate框架第二天

    ### Hibernate的持久化类 ### ---------- **什么是持久化类** 1. 持久化类:就是一个Java类(咱们编写的JavaBean),这个Java类与表建立了映射关系就可以成为 ...

  5. Hibernate **关于hibernate4.3版本之后org.hibernate.service.ServiceRegistryBuilder被弃用**

    之前一直都是使用hibernate4.2.21的我,有一天突然没有使用本地的jar包而是让IDEA自动下载最新版本的hibernate5.2.2之后,发现有几个经常使用的方法报错了. //创建配置对象 ...

  6. 使用hibernate与mysql时数据不能插入的原因及解决办法

    1.背景 之前从没用过hibernate,因此在网上搜了一下hibernate快速入门方面的信息,最后我按照<Myeclipse Hibernate 快速入门 中文版>(CSDN,百度文库 ...

  7. IntelliJ IDEA下自动生成Hibernate映射文件以及实体类

    转自:https://blog.csdn.net/qq_34197553/article/details/77718925 1.构建项目并添加项目结构配置以及配置初始参数 1.1.如图将基本的架子搭建 ...

  8. Spring Hibernate JPA 联表查询 复杂查询

    (转自:http://www.cnblogs.com/jiangxiaoyaoblog/p/5635152.html) 今天刷网,才发现: 1)如果想用hibernate注解,是不是一定会用到jpa的 ...

  9. 5 -- Hibernate的基本用法 --2 1 Hibernate 下载和安装

    1. 下载Hibernate压缩包 2. 解压:文件结构 ⊙ documentation : 该路径下存放了Hibernate的相关文档,包括Hibernate的参考文档和API文档等. ⊙ lib ...

  10. Hibernate的一级缓存

    Hibernate的一级缓存 什么是缓存:缓存将数据库/硬盘上文件中数据,放入到缓存中(就是内存中一块空间).当再次使用的使用,可以直接从内存中获取 缓存的好处:提升程序运行的效率.缓存技术是Hibe ...

最新文章

  1. shiro整合oauth
  2. mysql 让别人连接我的数据库
  3. 移动端分步注册_移动应用程序的可用性测试:分步指南
  4. maven离线安装jar包
  5. 人工智能与深度学习概念(5)——目标检测-RCNN
  6. 点云应用于电力行业助力输配电安全距离检测分析以及精细化巡检
  7. excel转word_这3种Word、Excel格式不变的互转方法,实在太好用了
  8. 【云原生之k8s】k8s安全机制
  9. 消防工程师 8.2 防排烟系统-防烟
  10. 代码回现 | 如何实现交易反欺诈?
  11. 基于Linux+ARM的远程视频监控--硬件篇
  12. 人工智能和图像处理方面的各种会议的评级
  13. 计算机硬盘做u盘启动不了,u盘启动盘读不出来硬盘如何解决_电脑U盘启动找不到硬盘的解决教程...
  14. 烂泥:OpenLDAP安装与配置
  15. h5 生成图片并保存到手机(浏览器)
  16. 平面几何----用梅涅劳斯定解20年一道高三数学模拟题
  17. 首次曝光!唯一全域最高等级背后的阿里云云原生安全全景图
  18. c语言clip函数,深入理解裁剪(clip)
  19. Puppy linux的引导安装问题
  20. Spread for WPF-Silverlight 新功能使用指南

热门文章

  1. 高性能服务器设计——模块间通信(转载)
  2. sdibt 1244类似于拓扑排序
  3. C#windows服务中的Timer控件的使用
  4. 【体系结构】Oracle如何保证提交的数据不丢失
  5. linux之我常用的20条命令(之一)
  6. Spring依赖查找中的常见异常
  7. 别让自己成为一名废弃的程序员
  8. php url路径问题和php文件以绝对路径引入
  9. 广船国际:“红帆”远航
  10. centos7 mysql5.6.34_CentOS7.0环境下MySQL5.6.34安装教程