分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 代码编程

六、hibernate表与表之间的关系(多对多关系)

发布时间:2023-09-06 02:27责任编辑:沈小雨关键词:暂无标签

多对多关系

创建实体类和对应映射文件

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 ????@Override34 ????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 ????@Override38 ????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> 

测试

@Testpublic 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 FKsrw3nh8oe5xhmqqxm2qng952tHibernate: alter table teach_stu drop foreign key FKtc48sy6cweqkufd4c777i8vspHibernate: drop table if exists studentHibernate: drop table if exists teach_stuHibernate: drop table if exists teacherHibernate: 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 completeHibernate: 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: 2300011: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 statements11: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 FKsrw3nh8oe5xhmqqxm2qng952tHibernate: alter table teach_stu drop foreign key FKtc48sy6cweqkufd4c777i8vspHibernate: drop table if exists studentHibernate: drop table if exists teach_stuHibernate: drop table if exists teacherHibernate: 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 completeHibernate: 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>

测试方法

@Testpublic 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 completeHibernate: 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" >

六、hibernate表与表之间的关系(多对多关系)

原文地址:https://www.cnblogs.com/qf123/p/10173799.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved