1.
拿Classes和Student为例。
package com.test;
import java.util.Set;
public class Classes {
private Integer classesId;
private String classesName;
private Set students;
public Set getStudents() {
return students;
}
public void setStudents(Set students) {
this.students = students;
}
public Integer getClassesId() {
return classesId;
}
public void setClassesId(Integer classesId) {
this.classesId = classesId;
}
public String getClassesName() {
return classesName;
}
public void setClassesName(String classesName) {
this.classesName = classesName;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.Classes" table="classes">
<id name="classesId" column="classes_id">
<generator class="native"/>
</id>
<property name="classesName" column="classes_name"/>
<set name="students">
<!-- key是外键 -->
<key column="cls_id"/>
<one-to-many class="com.test.Student"/>
</set>
</class>
</hibernate-mapping>
package com.test;
public class Student {
private Integer studentId;
private String studentName;
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.Student" table="student">
<id name="studentId" column="student_id">
<generator class="native"/>
</id>
<property name="studentName" column="student_name"/>
</class>
</hibernate-mapping>
测试类:
public void testAdd(){
Session session = HibernateUtils.getSession();
session.beginTransaction();
Student student1 = new Student();
student1.setStudentName("zhangsan");
Student student2 = new Student();
student2.setStudentName("lisi");
Classes classes = new Classes();
classes.setClassesName("02-1");
Set students = new HashSet();
students.add(student1);
students.add(student2);
classes.setStudents(students);
session.save(classes);
session.getTransaction().commit();
HibernateUtils.closeSession(session);
}
这时会报org.hibernate.TransientObjectException异常,说明save classes对象时,student1和student2还是游离态对象,但是因为是一对多关系,所以一方Classes要知道多方的信息,这时多方还是游离态,所以就报错了。
可以设置让 Student对象级联更新。如下:
<set name="students" cascade="all">
<!-- key是外键 -->
<key column="cls_id"/>
<one-to-many class="com.test.Student"/>
</set>
执行的sql代码如下:
Hibernate: insert into classes (classes_name) values (?)
Hibernate: insert into student (student_name) values (?)
Hibernate: insert into student (student_name) values (?)
Hibernate: update student set cls_id=? where student_id=?
Hibernate: update student set cls_id=? where student_id=?
可以看出是先insert,再update.这样有个缺点:如果数据量很大时会严重影响效率。可以通过inverse标签反转下。
<set name="students" cascade="all" inverse="true">
<!-- key是外键 -->
<key column="cls_id"/>
<one-to-many class="com.test.Student"/>
</set>
执行的sql如下:
Hibernate: insert into classes (classes_name) values (?)
Hibernate: insert into student (student_name) values (?)
Hibernate: insert into student (student_name) values (?)
但是这时数据库记录里外键的值是null.
所以还需要配置双向关联。
Studnet.hbm.xml里添加:
<many-to-one name="classes" column="cls_id"></many-to-one>
Student.java里添加:
private Classes classes;
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
测试类里添加:
classes.setStudents(students);
student1.setClasses(classes);
student2.setClasses(classes);
如果不设置级联更新,也可以这样:
Classes.hbm.xml
<set name="students" inverse="true" >
<!-- key是外键 -->
<key column="cls_id"/>
<one-to-many class="com.test.Student"/>
</set>
Student.hbm.xml不变:
<many-to-one name="classes" column="cls_id"></many-to-one>
测试类:
public void testAdd1(){
Session session = HibernateUtils.getSession();
session.beginTransaction();
Student student1 = new Student();
student1.setStudentName("zhangsan");
Student student2 = new Student();
student2.setStudentName("lisi");
Classes classes = new Classes();
classes.setClassesName("02-1");
student1.setClasses(classes);
student2.setClasses(classes);
session.save(classes);
session.save(student1);
session.save(student2);
session.getTransaction().commit();
HibernateUtils.closeSession(session);
}
执行sql:
Hibernate: insert into classes (classes_name) values (?)
Hibernate: insert into student (student_name, cls_id) values (?, ?)
Hibernate: insert into student (student_name, cls_id) values (?, ?)
总结:
1.都需要设置双向关联(指的是配置文件)
2.都需要设置inverse=true。(对级联来说,不用先insert,再update了)
3.设置了 cascade以后,save的是Classes对象,Student会级联保存。前提是双方关联:
classes.setStudents(students);
student1.setClasses(classes);
student2.setClasses(classes);
4.没有设置cascade的话,save的是Student对象。不过save Student对象以前,要先save Classes对象。
分享到:
相关推荐
NULL 博文链接:https://xiangtui.iteye.com/blog/680938
Hibernate-one-to-many
免费为大家服务 Hibernate one-to-many-annotation
NULL 博文链接:https://zhouxianglh.iteye.com/blog/569471
如果在”一“一端维护一对多关联关系,hibernate会发出多余的udpate语句,所以我们一般在多的一端来维护关联关系。 加上inverse="true"这个属性,就可以强制在多的一端维护关系了。
Hibernate应用例子many-to-many
深入理解hibernate many-to-one(多对一)及 cascade(级联).
Hibernate中many-to-one关系的编写_远航的水手
Hibernate中many-to-one关系的编写_远航的水手.htm
NULL 博文链接:https://yinxiaoyong.iteye.com/blog/426752
NULL 博文链接:https://liqita.iteye.com/blog/1497077
上web tools课时老师发的关于hibernate的教程之一。大概内容看标题就知道了。需要注意的是文档全部是英文的。英文不好的童鞋就不要下了。
一对多Hibernate
一对多Hibernate
使用MySql示例的带有Hibernate的Spring Data JPA 该项目使用MySql Example描述了带有Spring Data JPA和Hibernate的Spring Boot示例。 描述 该项目显示了存储在MySql数据库中的用户列表。 使用以下端点,可以实现...
hibernate对象三状态及OneToOne&OneToMany&ManyToMany讲解,代码示例,数据库示例!非常全面
说明了hibernate one-to-many
How to do various mappings, including one-to-one mapping, many-to-one mapping, collection mapping, component mapping, and inheritance mapping How to use Hibernate Query Language (HQL) How to perform ...
hibernate many to one 完整的程序,配套的jar 包,还有对应的数据库。 有清晰的注释!
many-to-one 配置详解 讲的很清楚 适合新手 值得下载