六、hibernate表与表之间的关系(多对多关系)
多对多关系
创建实体类和对应映射文件
Student.java
1 package com.qf.entity; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 public class Student { 7 8 private Long sid; 9 private String sname; 10 //一个学生可以有很多个老师 11 private Set<Teacher> teachs = new HashSet<>(); 12 13 public Long getSid() { 14 return sid; 15 } 16 public void setSid(Long sid) { 17 this.sid = sid; 18 } 19 20 public String getSname() { 21 return sname; 22 } 23 public void setSname(String sname) { 24 this.sname = sname; 25 } 26 27 public Set<Teacher> getTeachs() { 28 return teachs; 29 } 30 public void setTeachs(Set<Teacher> teachs) { 31 this.teachs = teachs; 32 } 33 @Override 34 public String toString() { 35 return "Student [sid=" + sid + ", sname=" + sname + ", teachs=" + teachs + "]"; 36 } 37 38 }
View Code
Student.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><!-- 配置表与实体的映射关系 --><class name="com.qf.entity.Student" table="student"><id name="sid" column="sid"><generator class="native"></generator></id><property name="sname" column="sname"/><set name="teachs" table="teach_stu" ><key column="sid"/><many-to-many class="com.qf.entity.Teacher" column="tid" /></set></class>
</hibernate-mapping>
Teacher.java
1 package com.qf.entity; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 public class Teacher { 7 private long tid; 8 private String tname; 9 private String course; 10 //一个教师可以有多个学生 11 private Set<Student> stus = new HashSet<Student>(); 12 13 public Set<Student> getStus() { 14 return stus; 15 } 16 public void setStus(Set<Student> stus) { 17 this.stus = stus; 18 } 19 public long getTid() { 20 return tid; 21 } 22 public void setTid(long tid) { 23 this.tid = tid; 24 } 25 public String getTname() { 26 return tname; 27 } 28 public void setTname(String tname) { 29 this.tname = tname; 30 } 31 public String getCourse() { 32 return course; 33 } 34 public void setCourse(String course) { 35 this.course = course; 36 } 37 @Override 38 public String toString() { 39 return "Teacher [tid=" + tid + ", tname=" + tname + ", course=" + course + "]"; 40 } 41 42 43 }
View Code
Teacher.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><!-- 配置表与实体的映射关系 --><class name="com.qf.entity.Teacher" table="teacher"><id name="tid" column="tid"><generator class="native"/></id><property name="tname" column="tname"/><property name="course" column="course"/><set name="stus" table="teach_stu"><key column="tid"></key><many-to-many class="com.qf.entity.Student" column="sid"/></set></class>
</hibernate-mapping>
测试
@Test
public void test() {Session session = SessionFactoryUtil.getSession();Transaction tx = session.beginTransaction();//创建两个教师对象,三个学生对象//学生选择老师Teacher t1 = new Teacher();t1.setTname("张老师");Teacher t2 = new Teacher();t2.setTname("李老师");Student s1 = new Student();s1.setSname("张三");Student s2 = new Student();s2.setSname("李四");Student s3 = new Student();s3.setSname("王五");//学生和老师之间建立双向关系//多对多关系建立双向关系后,双方必须有一方放弃维护外键关系权(inverse),否则会因为中间表主键重复抛出异常s1.getTeachs().add(t1);s1.getTeachs().add(t2);s3.getTeachs().add(t1);s2.getTeachs().add(t2);t1.getStus().add(s1);t1.getStus().add(s3);t2.getStus().add(s2);t2.getStus().add(s1);session.save(s1);session.save(s2);session.save(s3);session.save(t1);session.save(t2);tx.commit();
}
-------------------------------------console-------------------------------------
Hibernate: alter table teach_stu drop foreign key FKsrw3nh8oe5xhmqqxm2qng952t
Hibernate: alter table teach_stu drop foreign key FKtc48sy6cweqkufd4c777i8vsp
Hibernate: drop table if exists student
Hibernate: drop table if exists teach_stu
Hibernate: drop table if exists teacher
Hibernate: create table student (sid bigint not null auto_increment, sname varchar(255), primary key (sid))
Hibernate: create table teach_stu (tid bigint not null, sid bigint not null, primary key (sid, tid))
Hibernate: create table teacher (tid bigint not null auto_increment, tname varchar(255), course varchar(255), primary key (tid))
Hibernate: alter table teach_stu add constraint FKsrw3nh8oe5xhmqqxm2qng952t foreign key (sid) references student (sid)
Hibernate: alter table teach_stu add constraint FKtc48sy6cweqkufd4c777i8vsp foreign key (tid) references teacher (tid)
11:21:37,135 INFO SchemaExport:464 - HHH000230: Schema export complete
Hibernate: insert into student (sname) values (?)
Hibernate: insert into student (sname) values (?)
Hibernate: insert into student (sname) values (?)
Hibernate: insert into teacher (tname, course) values (?, ?)
Hibernate: insert into teacher (tname, course) values (?, ?)
Hibernate: insert into teach_stu (sid, tid) values (?, ?)
Hibernate: insert into teach_stu (sid, tid) values (?, ?)
Hibernate: insert into teach_stu (sid, tid) values (?, ?)
Hibernate: insert into teach_stu (sid, tid) values (?, ?)
Hibernate: insert into teach_stu (tid, sid) values (?, ?)
11:21:37,270 WARN SqlExceptionHelper:127 - SQL Error: 1062, SQLState: 23000
11:21:37,271 ERROR SqlExceptionHelper:129 - Duplicate entry '1-1' for key 'PRIMARY'
11:21:37,271 INFO AbstractBatchImpl:193 - HHH000010: On release of batch it still contained JDBC statements
11:21:37,272 ERROR SessionImpl:2994 - HHH000346: Error during managed flush [could not execute statement]
原因
测试中因为建立了双向关系,所以teacher和student都会去维护外键,导致相同的(1,1)会两次插入中间关系表teach_stu中
解决办法
一方放弃维护外键关系权。一般被动主体放弃维护外键权,比如学生选择老师,老师放弃维护外键权;老师选择学生,学生放弃维护外键权
修改Teacher.hbm.xml:<set name="stus" table="teach_stu" inverse="true">
-------------------------------------console-------------------------------------
Hibernate: alter table teach_stu drop foreign key FKsrw3nh8oe5xhmqqxm2qng952t
Hibernate: alter table teach_stu drop foreign key FKtc48sy6cweqkufd4c777i8vsp
Hibernate: drop table if exists student
Hibernate: drop table if exists teach_stu
Hibernate: drop table if exists teacher
Hibernate: create table student (sid bigint not null auto_increment, sname varchar(255), primary key (sid))
Hibernate: create table teach_stu (tid bigint not null, sid bigint not null, primary key (sid, tid))
Hibernate: create table teacher (tid bigint not null auto_increment, tname varchar(255), course varchar(255), primary key (tid))
Hibernate: alter table teach_stu add constraint FKsrw3nh8oe5xhmqqxm2qng952t foreign key (sid) references student (sid)
Hibernate: alter table teach_stu add constraint FKtc48sy6cweqkufd4c777i8vsp foreign key (tid) references teacher (tid)
11:30:43,077 INFO SchemaExport:464 - HHH000230: Schema export complete
Hibernate: insert into student (sname) values (?)
Hibernate: insert into student (sname) values (?)
Hibernate: insert into student (sname) values (?)
Hibernate: insert into teacher (tname, course) values (?, ?)
Hibernate: insert into teacher (tname, course) values (?, ?)
Hibernate: insert into teach_stu (sid, tid) values (?, ?)
Hibernate: insert into teach_stu (sid, tid) values (?, ?)
Hibernate: insert into teach_stu (sid, tid) values (?, ?)
Hibernate: insert into teach_stu (sid, tid) values (?, ?)
数据成功插入数据库
级联保存
保存学生级联保存教师
主体是学生,所以修改学生的映射文件Student.hbm.xml
<hibernate-mapping><!-- 配置表与实体的映射关系 --><class name="com.qf.entity.Student" table="student"><id name="sid" column="sid"><generator class="native"></generator></id><property name="sname" column="sname"/><set name="teachs" table="teach_stu" cascade="save-update" ><key column="sid"/><many-to-many class="com.qf.entity.Teacher" column="tid" /></set></class>
</hibernate-mapping>
测试方法
@Test
public void test() {Session session = SessionFactoryUtil.getSession();Transaction tx = session.beginTransaction();//保存学生级联保存教师Teacher t1 = new Teacher();t1.setTname("张老师");Student s1 = new Student();s1.setSname("张三");t1.getStus().add(s1);s1.getTeachs().add(t1);session.save(s1);tx.commit();
}
-------------------------------------console-------------------------------------
Hibernate: create table student (sid bigint not null auto_increment, sname varchar(255), primary key (sid))
Hibernate: create table teach_stu (tid bigint not null, sid bigint not null, primary key (sid, tid))
Hibernate: create table teacher (tid bigint not null auto_increment, tname varchar(255), course varchar(255), primary key (tid))
Hibernate: alter table teach_stu add constraint FKsrw3nh8oe5xhmqqxm2qng952t foreign key (sid) references student (sid)
Hibernate: alter table teach_stu add constraint FKtc48sy6cweqkufd4c777i8vsp foreign key (tid) references teacher (tid)
14:22:37,418 INFO SchemaExport:464 - HHH000230: Schema export complete
Hibernate: insert into student (sname) values (?)
Hibernate: insert into teacher (tname, course) values (?, ?)
Hibernate: insert into teach_stu (sid, tid) values (?, ?
级联删除(一般不使用)
想以哪一方为主体删除另一方,就在哪一方映射文件中配置cascade属性:
<set name="teachs" table="teach_stu" cascade="delete" >
转载于:https://www.cnblogs.com/qf123/p/10173799.html
六、hibernate表与表之间的关系(多对多关系)相关推荐
- 6.2 、MyBatis 高级映射(resultMap 标签多表联查 , 一对多,多对一关系)
文章目录 一.创建表结构,添加数据,实现表中数据的关联关系 二. association 标签:用于一对一.多对一场景使用 1.实现一对一,多对一关系结果集映射 1.1 按照查询嵌套处理 1.2 按照 ...
- SQL外键foreign key 表与表之间的三种关系
表与表之间的三种关系 多对一关系表 注意事项: 一对多表关系,外键字段建在多的一方. 在创建表的时候,一定要先建被关联表. 在录入数据的时候,也必须先录入被关联表. 删除 一定要先删除主键表,才可以删 ...
- 表与表之间的关系,修改表,复制表
表与表之间的关系 外键 外键就是从来帮助我们建立表与表之间关系的 foreign key 表关系 表与表只有四种关系 一对多关系 多对多关系 一对一关系 多对一关系 一对多 SQL语句建立表关系 1. ...
- mysql表与表之间常见的映射关系_数据库表关联关系的基础知识
表与表之间的关联关系一共有三种类型,一对一.多对一.和多对多,下面我们分别对这三种类型展开进行讨论. 一对一 表示两个表中的数据必须是一一对应的关系.这种场景其实并不是很常见,我们还是通过例子来直观地 ...
- 多对多关系的多表关联查询
1.什么是多对多关系 多对多关系(百度):多对多关系是关系数据库中两个表之间的一种关系, 该关系中第一个表中的一个行可以与第二个表中的一个或多个行相关.第二个表中的一个行也可以与第一个表中的一个或多个 ...
- mysql一对多、多对多关系表的建立与查询
夏梦,只写最简洁最有效的教程-欢迎关注 在实际的开发场景中,我们会建立非常多的表,其中一对多和多对多关系表的建立和查询对与一些刚接触的人来说可能会有些疑惑,所以为了解决这些疑惑,有了这篇文章. 注意: ...
- 实体 联系 模型mysql_实体关系模型和关系模型之间有什么区别?
你有倒退. ER模型中的关系是显式定义的,而在关系模型中则是隐式的. 否.每个关系模型(RM)数据库基表和查询结果都代表一个应用程序关系.实体关系建模(E-RM)模式只是一种组织(但使用不足和指定不足 ...
- 什么是数据库中的多对多关系?
什么是数据库建模中的多对多关系?如何在数据库中实现这种关系?本文中的示例将回答这些问题. 多对多关系可能是在数据库中显示的最棘手的关系.因此,我在本文中的第一步将是解释它们是什么.然后,我将继续给你几 ...
- Laravel中的多对多关系
多对对关系 多对多的关系比一对一和一对多关系稍微复杂些. 如: 一个用户可以选择多门课程,一个课程可以被多个用户选择. 用户表和课程表之间就是一个多对多的关系: 一个用户可以拥有多个角色,一个角色可以 ...
最新文章
- Android 为不同的语言和硬件创建资源
- iOS 跳转App的二三事
- Django的Form表单
- java算法之冒泡排序法
- CF1415D:XOR-gun(异或)
- 用python和sympy库解决方程组问题_Python语言 SymPy库数学方程问题——线性方程组篇...
- 触发更新机制_王者荣耀1.14更新:11名英雄调整,韩信加强,鲁班大师重做
- 巧妙布局的APP界面模板,让你的作品更有吸引力
- 认识activiti与flowable的区别---工作流工作笔记001
- E20170816-mk
- 蔡俊锋 web API 开发规范
- php基础之时间格式化
- JAVA中SSH框架
- 新版三证合一营业执照组织机构代码是哪9位及统一社会信用代码怎么获取9位全国企业组织机构代码查询入口
- Linux的下Ip计算器
- html 复制链接功能,h5分享功能[通过复制网页链接分享]
- JAVA蘑菇西餐,蘑菇的二十二种西餐做法,简单易上手,让你品尝不一样的风味...
- Android获取本机号码闪退,手机号码是移动的,现在手机已经停机,想充话费却不知道本机号码,肿么查询本机号码?()...
- 关闭 Gatekeeper
- 计算机远程控制设计,远程控制软件的设计与实现
热门文章
- CS/BS架构是什么?以及他们的区别
- 【设计模式学习笔记1】原型法
- 19c打补丁简易步骤
- 浅谈人工智能专业,作为普通学生对未来的看法
- yum下载软件包报错 you could try using --skip-broken to work aroundthe problem you should tyr running: rpm
- !《掘地求生》制作心得及源码分享 unity制作
- 「掘虫者说」Docker部署组件正常,安全规则正常配置,服务telnet不通
- 天线工程手册_“大神”给工控工程师快速成长的6点建议,看完你会少走弯路...
- 多元线性回归分析练习题
- 数仓 - 促销敏感度、评论敏感度