java框架之Hibernate(3)-一对多和多对多关系操作
一对多
例:一个班级可以有多个学生,而一个学生只能属于一个班级。
模型
package com.zze.bean;
import java.util.HashSet;
import java.util.Set;
public class Class {
private Integer id;
private String name;
private Set<Student> students = new HashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
班级:com.zze.bean.Class
package com.zze.bean;
import java.util.Date;
public class Student {
private Integer id;
private String name;
private Integer age;
private Date birthday;
private String address;
private Class clazz;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Class getClazz() {
return clazz;
}
public void setClazz(Class clazz) {
this.clazz = clazz;
}
}
学生:com.zze.bean.Student
配置文件
<?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.zze.bean.Class" table="class">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="32"/>
<!--
set :
name : ‘多’的一方在当前类中的属性名
-->
<set name="students">
<!--
key :
column : 外键表中的关联当前类对应表的外键名称
-->
<key column="cid"/>
<!--
one-to-many : 标识一对多关系
class : ‘多’的一方全限定类名
-->
<one-to-many class="com.zze.bean.Student"/>
</set>
</class>
</hibernate-mapping>
com/zze/bean/Class.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.zze.bean.Student" table="student">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="32"/>
<property name="age"/>
<property name="birthday"/>
<property name="address"/>
<!--
many-to-one : 标识多对一关系
name : ‘一’的一方在当前类中属性名
column : 外键名称
class : ‘一’的一方的全限定类名
-->
<many-to-one name="clazz" column="cid" class="com.zze.bean.Class"/>
</class>
</hibernate-mapping>
com/zze/bean/Student.hbm.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://192.168.208.153:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping resource="com/zze/bean/Class.hbm.xml"></mapping>
<mapping resource="com/zze/bean/Student.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
hibernate.cfg.xml
普通操作
@Test
public void test1() {
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 创建一个班级
Class clazz = new Class();
clazz.setName("1班");
// 创建两个学生
Student student1 = new Student();
student1.setName("张三");
Student student2 = new Student();
student2.setName("李四");
// 让班级关联学生
clazz.getStudents().add(student1);
clazz.getStudents().add(student2);
// 让学生关联班级
student1.setClazz(clazz);
student2.setClazz(clazz);
// 保存班级
session.save(clazz);
// 保存学生
session.save(student1);
session.save(student2);
transaction.commit();
}

例 1:两方关联,保存两方 - 新建一个班级,新建两个学生,班级主动关联学生,学生也主动关联班级,保存班级,再保存学生,成功
@Test
public void test2() {
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 创建一个班级
Class clazz = new Class();
clazz.setName("1班");
// 创建两个学生
Student student1 = new Student();
student1.setName("张三");
Student student2 = new Student();
student2.setName("李四");
// 让班级关联学生
clazz.getStudents().add(student1);
clazz.getStudents().add(student2);
// 让学生关联班级
student1.setClazz(clazz);
student2.setClazz(clazz);
// 保存班级
session.save(clazz);
transaction.commit();
/*
抛异常:org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.zze.bean.Student
原因是:保存班级时,班级关联的学生为瞬时态对象,不能与瞬时态对象建立关系。
*/
}
例 2:两方关联,保存一方 - 新建一个班级,新建两个学生,班级主动关联学生,学生也主动关联班级,只保存班级,异常,需使用下面的级联保存。
级联操作
- 级联:
-
级联指的是:操作一个对象的时候,是否会同时操作其关联的对象。
- 级联的方向性:
-
操作一的一方的时候,是否会同时操作到多的一方。
操作多的一方的时候,是否会同时操作到一的一方。
级联保存或更新
保存‘一’级联保存‘多’:
<?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.zze.bean.Class" table="class"> <id name="id"> <generator class="native"/> </id> <property name="name" length="32"/> <set name="students" cascade="save-update"> <key column="cid"/> <one-to-many class="com.zze.bean.Student"/> </set> </class> </hibernate-mapping>com/zze/bean/Class.hbm.xml:修改‘一’(班级)的映射文件,在 set 标签中添加属性 cascade="save-update"
@Test public void test3() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 创建一个班级 Class clazz = new Class(); clazz.setName("1班"); // 创建两个学生 Student student1 = new Student(); student1.setName("张三"); Student student2 = new Student(); student2.setName("李四"); // 让班级关联学生 clazz.getStudents().add(student1); clazz.getStudents().add(student2); // 保存班级级联保存学生 session.save(clazz); transaction.commit(); }
例 3:‘一’方关联,保存‘一’方 - 新建一个班级,新建两个学生,班级主动关联学生,只保存班级,级联保存了学生,成功
保存‘多’级联保存‘一’:
<?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.zze.bean.Student" table="student"> <id name="id"> <generator class="native"/> </id> <property name="name" length="32"/> <property name="age"/> <property name="birthday"/> <property name="address"/> <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" cascade="save-update"/> </class> </hibernate-mapping>com/zze/bean/Student.hbm.xml:修改‘多’(学生)的映射文件,在 many-to-one 标签中添加属性 cascade="save-update"
@Test public void test4(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 创建一个班级 Class clazz = new Class(); clazz.setName("1班"); // 创建两个学生 Student student1 = new Student(); student1.setName("张三"); Student student2 = new Student(); student2.setName("李四"); // 让学生关联班级 student1.setClazz(clazz); student2.setClazz(clazz); // 保存学生级联保存班级 session.save(student1); session.save(student2); transaction.commit(); }
例 4:‘多’方关联,保存‘多’方 - 新建一个班级,新建两个学生,学生主动关联班级,只保存学生,级联保存了班级,成功
级联删除
假如表中已有如下数据:

删除‘一’级联删除‘多’:
<?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.zze.bean.Class" table="class"> <id name="id"> <generator class="native"/> </id> <property name="name" length="32"/> <set name="students" cascade="save-update,delete"> <key column="cid"/> <one-to-many class="com.zze.bean.Student" /> </set> </class> </hibernate-mapping>com/zze/bean/Class.hbm.xml:修改‘一’(班级)的映射文件,在 set 标签中添加属性 cascade="delete"
@Test public void test5() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.get(Class.class, 1); session.delete(clazz); transaction.commit(); }
例 5:删除班级,级联删除该班级下所有学生。
删除‘多’级联删除‘一’:
<?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.zze.bean.Student" table="student"> <id name="id"> <generator class="native"/> </id> <property name="name" length="32"/> <property name="age"/> <property name="birthday"/> <property name="address"/> <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" cascade="save-update,delete"/> </class> </hibernate-mapping>com/zze/bean/Student.hbm.xml:修改‘多’(学生)的映射文件,在 many-to-one 标签中添加属性 cascade="delete"
@Test public void test6() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = session.get(Student.class, 1); session.delete(student); transaction.commit(); // 级联删除‘一’的一方,将其它关联‘一’的一方的数据的外键设为 null。 // 如果‘一’的一方也设置了级联删除,那么所有关联‘一’的一方的数据都会被删除。 }
例 6:删除学生,级联删除该学生所属班级。
放弃维护外键关系
假入表中已有如下数据:

先要把张三从 1 班转到 2 班:
@Test
public void test7(){
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Student student = session.get(Student.class, 1); // 获取张三
Class clazz = session.get(Class.class, 1); // 获取 2 班
clazz.getStudents().add(student);
student.setClazz(clazz);
transaction.commit();
/*
此时会执行一下两条 SQL:
Hibernate:
update
student
set
name=?,
age=?,
birthday=?,
address=?,
cid=?
where
id=?
Hibernate:
update
student
set
cid=?
where
id=?
*/
}
例 7:
执行两条 SQL 的原因是:在上述代码中获取了两个持久态对象,并且在事务提交时两个持久态对象的属性都发生了变化,所以 Hibernate 发出了两条 SQL。
但显然这个操作其实一条 SQL 就能搞定的,这个时候就需要控制一方不维护外键关系了。
‘一’的一方放弃维护外键关系:
<?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.zze.bean.Class" table="class">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="32"/>
<set name="students" cascade="save-update" inverse="true">
<key column="cid"/>
<one-to-many class="com.zze.bean.Student" />
</set>
</class>
</hibernate-mapping>
com/zze/bean/Class.hbm.xml:修改‘一’(班级)映射文件,在 set 标签中添加属性 inverse="true"
依旧是执行上述“例 7”代码,会发现只会由‘多’(学生)的一方发出一条 update 语句。
在 Hibernate 中,‘多’的一方不可以放弃维护外键关系。
- 为什么‘多’的一方不能放弃维护外键关系?换句话说为什么 Hibernate 要让多的一方来维护关系?
-
原因是当‘一’的一方维护关系时,Hibernate 会额外发出一条 select 语句查出它所关联的所有的多的一方,显然没必要。而多的一方维护关系就比较简单了,直接 update 它本身的外键即可。
看到过一个有趣应景的说法:十三亿人民(‘多’)记住(维护)国家领导人的名字很简单,但要想国家领导人(‘一’)记住(维护)十三亿就不可能了。
- 理解 inverse 和 cascade:
-
@Test public void test8() { // com/zze/bean/Class.hbm.xml 的 set 中设置了 cascade="save-update"、inverse="true" Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = new Student(); student.setName("王五"); Class clazz = session.get(Class.class, 2); // 获取 1 班 clazz.getStudents().add(student); session.save(clazz); transaction.commit(); /* 上述代码执行结果会是怎么样? 先明确 cascade 和 inverse 的作用: cascade:为 save-update,即 Class 会级联保存和更新 Student。 inverse:为 true,即 Class 放弃维护外键关系。 首先 session 保存的是 clazz,clazz 是持久态对象。 在事务提交时 clazz 的外键字段 students 发生了变化,添加了 student, 班级有级联操作学生的能力,所以“王五”这个 student 会被保存到数据库。 而班级放弃了维护外键关系,所以“王五”这个 student 添加到数据库后对应的外键字段为 null。 结果如下: mysql> select * from student; +----+--------+------+----------+---------+------+ | id | name | age | birthday | address | cid | +----+--------+------+----------+---------+------+ | 1 | 张三 | NULL | NULL | NULL | 1 | | 2 | 王五 | NULL | NULL | NULL | NULL | +----+--------+------+----------+---------+------+ 2 rows in set (0.00 sec) */ }例 8:
多对多
例:一名学生可以选多门课程,一门课程也可以被多名学生选择:
模型
package com.zze.bean;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Student {
private Integer id;
private String name;
private Integer age;
private Date birthday;
private String address;
private Class clazz;
private Set<Course> courses = new HashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Class getClazz() {
return clazz;
}
public void setClazz(Class clazz) {
this.clazz = clazz;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
}
学生:com.zze.bean.Student
package com.zze.bean;
import java.util.HashSet;
import java.util.Set;
public class Course {
private Integer id;
private String name;
private Set<Student> students = new HashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
课程:com.zze.bean.Course
配置文件
<?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.zze.bean.Student" table="student">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="32"/>
<property name="age"/>
<property name="birthday"/>
<property name="address"/>
<many-to-one name="clazz" column="cid" class="com.zze.bean.Class" cascade="save-update,delete"/>
<set name="courses" table="student_course">
<!--
key :
column : 当前对象类对应中间表的外键名称
-->
<key column="studentId"/>
<!--
many-to-many : 标识多对多关系
class : 对方类全路径
column : 对方对应中间表的外键名称
-->
<many-to-many class="com.zze.bean.Course" column="courseId"/>
</set>
</class>
</hibernate-mapping>
com/zze/bean/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.zze.bean.Course" table="course">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="32"/>
<set name="students" table="student_course">
<!--
key :
column : 当前对象类对应中间表的外键名称
-->
<key column="courseId"/>
<!--
many-to-many : 标识多对多关系
class : 对方类全路径
column : 对方对应中间表的外键名称
-->
<many-to-many class="com.zze.bean.Student" column="studentId"/>
</set>
</class>
</hibernate-mapping>
com/zze/bean/Course.hbm.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://192.168.208.153:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping resource="com/zze/bean/Class.hbm.xml"></mapping>
<mapping resource="com/zze/bean/Student.hbm.xml"></mapping>
<mapping resource="com/zze/bean/Course.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
hibernate.cfg.xml
普通操作
@Test
public void test9() {
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Student student = new Student();
student.setName("张三");
Course course = new Course();
course.setName("数学");
student.getCourses().add(course);
course.getStudents().add(student);
session.save(student);
session.save(course);
transaction.commit();
/*
抛异常:org.hibernate.exception.ConstraintViolationException: could not execute statement
原因:因为多对多关系的维护是依赖第三张中间表,而中间表的字段是两个分别关联多对多这两张表的主键的外键,
且这两个外键在中间表中组成了联合主键,而上述代码实际上进行了两次 insert 操作,这两次操作的内容违
反了联合主键约束,所以会抛出异常。
*/
}
例 9:两方关联,保存两方 - 新建一个学生,新建一个课程,让学生主动关联课程,也让课程主动关联学生,保存学生与课程,异常
分析原因后,可以得出结论,在多对多中两方关联时,必须有一方得放弃维护外键关系(一般是被动方放弃,即 Course 放弃),下面配置二选一:
<?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.zze.bean.Student" table="student">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="32"/>
<property name="age"/>
<property name="birthday"/>
<property name="address"/>
<many-to-one name="clazz" column="cid" class="com.zze.bean.Class" cascade="save-update,delete"/>
<set name="courses" table="student_course" inverse="true">
<!--
key :
column : 当前对象类对应中间表的外键名称
-->
<key column="studentId"/>
<!--
many-to-many : 标识多对多关系
class : 对方类全路径
column : 对方对应中间表的外键名称
-->
<many-to-many class="com.zze.bean.Course" column="courseId"/>
</set>
</class>
</hibernate-mapping>
com/zze/bean/Student.hbm.xml:修改 set 标签,添加属性 inverse="true"
<?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.zze.bean.Course" table="course">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="32"/>
<set name="students" table="student_course" inverse="true">
<!--
key :
column : 当前对象类对应中间表的外键名称
-->
<key column="courseId"/>
<!--
many-to-many : 标识多对多关系
class : 对方类全路径
column : 对方对应中间表的外键名称
-->
<many-to-many class="com.zze.bean.Student" column="studentId"/>
</set>
</class>
</hibernate-mapping>
com/zze/bean/Course.hbm.xml:修改 set 标签,添加属性 inverse="true"
修改配置后,再次执行 “例 9” 中代码,成功。
级联操作
级联保存或更新
<?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.zze.bean.Student" table="student"> <id name="id"> <generator class="native"/> </id> <property name="name" length="32"/> <property name="age"/> <property name="birthday"/> <property name="address"/> <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" cascade="save-update,delete"/> <set name="courses" table="student_course" cascade="save-update"> <!-- key : column : 当前对象类对应中间表的外键名称 --> <key column="studentId"/> <!-- many-to-many : 标识多对多关系 class : 对方类全路径 column : 对方对应中间表的外键名称 --> <many-to-many class="com.zze.bean.Course" column="courseId"/> </set> </class> </hibernate-mapping>com/zze/bean/Student.hbm.xml:修改 set 标签,添加属性 cascade="save-update"
@Test public void test10() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = new Student(); student.setName("张三"); Course course = new Course(); course.setName("数学"); student.getCourses().add(course); session.save(student); transaction.commit(); }例 10:一方关联,保存一方 - 新建一个学生,新建一个课程,让学生主动关联课程,保存学生,级联保存了课程,成功
级联删除
<?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.zze.bean.Student" table="student"> <id name="id"> <generator class="native"/> </id> <property name="name" length="32"/> <property name="age"/> <property name="birthday"/> <property name="address"/> <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" cascade="save-update,delete"/> <set name="courses" table="student_course" cascade="save-update,delete"> <!-- key : column : 当前对象类对应中间表的外键名称 --> <key column="studentId"/> <!-- many-to-many : 标识多对多关系 class : 对方类全路径 column : 对方对应中间表的外键名称 --> <many-to-many class="com.zze.bean.Course" column="courseId"/> </set> </class> </hibernate-mapping>com/zze/bean/Student.hbm.xml:修改 set 标签,添加属性 cascade="delete"
@Test public void test11() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = session.get(Student.class, 1); session.delete(student); transaction.commit(); }例 11:删除学生,级联删除该学生所选的课程
java框架之Hibernate(3)-一对多和多对多关系操作的更多相关文章
- Java基础-SSM之mybatis一对多和多对一关系映射
Java基础-SSM之mybatis一对多和多对一关系映射 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.准备测试环境(创建数据库表) 1>.创建customers表: ...
- Hibernate中一对多和多对一关系
1.单向多对一和双向多对一的区别? 只需要从一方获取另一方的数据时 就使用单向关联双方都需要获取对方数据时 就使用双向关系 部门--人员 使用人员时如果只需要获取对应部门信息(user.getdept ...
- Hibernate自身一对多和多对多关系映射
一对多关系映射大家都明白,关系双方都一个含有对方多个引用,但自身一对多很多同学都不明白什么意思,那么首先我就说明一下什么是自身一对多,其实也很好理解,自身一对多就是自身含有本身的多个引用,例如新闻类别 ...
- JAVA框架之Hibernate框架的学习步骤
首先介绍一下Java三大框架的关系 以CRM项目即客户关系管理项目示例 hibernate框架的学习路线: 1.学习框架入门,自己搭建框架,完成增删改查的操作 2.学习一级缓存,事物管理和基本查询 3 ...
- JPA一对多和多对一关系
1-m:多的一方为关系维护端,关系维护端负责外键纪录的更新,关系被维护端没有权力更新外键纪录. 维护端注解 @OneToMany(cascade = { CascadeType.PERSIST, Ca ...
- EF里一对一、一对多、多对多关系的配置和级联删除
本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个PersonPhoto类,表示用户照片类 /// < ...
- Django 一对多,多对多关系解析
[转]Django 一对多,多对多关系解析 Django 的 ORM 有多种关系:一对一,多对一,多对多. 各自定义的方式为 : 一对一: OneToOneField ...
- EF——一对一、一对多、多对多关系的配置和级联删除 04(转)
EF里一对一.一对多.多对多关系的配置和级联删除 本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个P ...
- django ORM模型表的一对多、多对多关系、万能双下划线查询
一.外键使用 在 MySQL 中,如果使用InnoDB引擎,则支持外键约束.(另一种常用的MyIsam引擎不支持外键) 定义外键的语法为fieldname=models.ForeignKey(to_c ...
随机推荐
- 稀疏贴图 SparseTexture
官方文档:https://docs.unity3d.com/Manual/SparseTextures.html 是一种虚拟贴图,可以动态的加载或卸载某一块tile.从而实现超大尺寸贴图的加载. 更新 ...
- [k8s] flexvolume workflow
- 9-11-Trie树/字典树/前缀树-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版
课本源码部分 第9章 查找 - Trie树/字典树/前缀树(键树) ——<数据结构>-严蔚敏.吴伟民版 源码使用说明 链接☛☛☛ <数据结构-C语言版>(严蔚 ...
- mysql索引知识简单记录
简介 今天记录下索引基础知识 1.mysql单表最多支持多少个索引,索引总长度为多少? 索引是在存储引擎中实现的,因此每种存储引擎的索引都不一定完全相同,并且每种存储引擎也不一定支持所有索引类型. ...
- nginx+lua的基本原理概念介绍
一. 概述 Nginx是一个高性能,支持高并发的,轻量级的web服务器.目前,Apache依然web服务器中的老大,但是在全球前1000大的web服务器中,Nginx的份额为22.4%.Nginx采用 ...
- 一致性 Hash 学习与实现
普通的 Hash 解决的是什么问题? 下图是一个普通的余数法构造的哈希表. 一般在编程中使用哈希表,某个 bucket 突然就没了的概率比较小,常见的是因为负载因子太大需要增加 bucket,然后 r ...
- 自己动手在win2003系统中添加虚拟网卡
运用虚拟网卡我们可以更好地使用我们的网络,那么在win2003中该怎么操作呢?下面就为大家介绍下具体的步骤 虚拟网卡是用软件来实现虚拟的网卡,通过运用虚拟网卡我们可以更好地使用我们的网络.但是虚拟 ...
- 易混HTML Entities与正确用法
在页面上,表示HTML实体有多种方式,比方有"&+name;"."&#+10进制ID"."&#x+16进制ID".而 ...
- Mysql Window 解压版卸载
windows如何彻底卸载mysql 如何彻底删除mysql 1.首先在windows服务中将mysql服务删掉,使用命令 sc delete mysql 2.在控制面板中卸载掉mysql. 3.清理 ...
- 让mysql 支持 emoji 表情
1.数据库配置 [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] ch ...