Hibernate 关联关系映射
关联关系映射
回顾:表与表之间关系
数据库中的表之间的关系
关系
1 对 多:一方表(主表)、多方表(从表)。从表中提供一个外检字段,添加约束主外键约束。从表的外检与主表的主键形成主外键关系
多对 多:
两个多表,都是主表
提供第三张表(中间表),是从表
提供两个字段,这两个字段分别是两个主表的外键
建议:两个字段合并在一起,生成联合主键
1 对 1
关联关系介绍
对象 与 对象 之间关系,使用面向对象的角度,分析对象之间的关系。
关联关系:一对多
实例
国家(1)--(*)城市
班级(1)--(*)学生
客户(1)--(*)订单
分析
客户(1)--(*)订单
代码
创建Teacher和Student
package cn.hibernate.bean;
import java.util.Set;
public class Teacher {
private Integer tId;
private String tName;
//一个老师对应多个学生
private Set<Student> stu;
public Integer gettId() {
return tId;
}
public void settId(Integer tId) {
this.tId = tId;
}
public String gettName() {
return tName;
}
public void settName(String tName) {
this.tName = tName;
}
public Set<Student> getStu() {
return stu;
}
public void setStu(Set<Student> stu) {
this.stu = stu;
}
}
package cn.hibernate.bean;
public class Student {
private Integer sId;
private String sName;
//一个学生对应一个老师
private Teacher teacher;
public Integer getsId() {
return sId;
}
public void setsId(Integer sId) {
this.sId = sId;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = 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 package="cn.hibernate.bean">
<class name="Teacher">
<id name="tId">
<generator class="native"></generator>
</id>
<property name="tName"></property>
<!-- 一对多 -->
<set name="stu">
<key column="teacher_id"></key>
<one-to-many class="Student" />
</set>
</class>
</hibernate-mapping>
<?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 package="cn.hibernate.bean">
<class name="Student">
<id name="sId">
<generator class="native"></generator>
</id>
<property name="sName"></property>
<!-- 多对一 class:写一(主表)的类型 -->
<many-to-one name="teacher" class="Teacher" column="teacher_id">
</many-to-one>
</class>
</hibernate-mapping>
API
@Test
public void demo05(){
//双向关联 :关联就是对外建数据的维护
/* 多方order,必须维护外键信息,如果已经有数据将不进行update更新
* 一方Teacher,默认只要关联就进行维护。但可以通过inverse进行设置。
* inverse="true"一方将放弃对外键数据维护。此时将减少一条update语句
*
* */
Session session = factory.openSession();
session.beginTransaction();
//1.创建对象
Teacher teacher = new Teacher();
teacher.settName("老师81");
Student stu = new Student();
stu.setsName("学生81");
//2.关联
stu.setTeacher(teacher); //teacher 还要关联,默认进行数据维护
teacher.getStu().add(stu); //stu必须维护数据,如果customer已经有OID,将不执行update
//保存
session.save(teacher);
session.save(stu);
session.getTransaction().commit();
session.close();
}
关联关系:双向关联
inverse配置
inverse=“true”如果是一对多关系,表示一方将放弃对外键数据维护。无论是否配置关联引用()
注意:多方必须维护外键数据,多方对应多表存在外键字段。
cascade 配置
介绍
级联操作:一个PO对象A关联 另一个 PO对象B,当A进行操作时,是否对B进行相应的操作。
取值:
save-update:级联保存或更新,当保存A,同时保存B,不需要手动执行saveBean()
级联保存
@Test
public void demo06(){
/*
* 级联保存:只保存学生
*
* */
Session session = factory.openSession();
session.beginTransaction();
//1.创建对象
Teacher teacher = new Teacher();
teacher.settName("测试12");
Student student = new Student();
student.setsName("测试学生12");
teacher.getStu().add(student);
student.setTeacher(teacher);
session.save(teacher);
session.getTransaction().commit();
session.close();
}
关联关系:双向关联
分析:数据库表之间关系
PO类分析
映射文件配置
代码编写多对多:
package cn.hibernate.manytomany;
import java.util.HashSet;
import java.util.Set;
//学生类
public class Student {
private Integer sId;
private String sName;
//多对多:多个学生(当前学生)学习不同的课 程
private Set<Course> courses = new HashSet<Course>();
public Integer getsId() {
return sId;
}
public void setsId(Integer sId) {
this.sId = sId;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
}
package cn.hibernate.manytomany;
import java.util.HashSet;
import java.util.Set;
//课程类
public class Course {
private Integer cId;
private String content;
private String teacher;
//多对多,不同课程(当前课程)被不同学生学习
private Set<Student> stu = new HashSet<Student>();
public Integer getcId() {
return cId;
}
public void setcId(Integer cId) {
this.cId = cId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTeacher() {
return teacher;
}
public void setTeacher(String teacher) {
this.teacher = teacher;
}
public Set<Student> getStu() {
return stu;
}
public void setStu(Set<Student> stu) {
this.stu = stu;
}
}
映射文件
<?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 package="cn.hibernate.manytomany">
<class name="Student">
<id name="sId">
<generator class="native"></generator>
</id>
<property name="sName"></property>
<set name="courses" table="s_student_course">
<key column="student_id"/>
<many-to-many class="cn.hibernate.manytomany.Course" column="course_id"/>
</set>
</class>
</hibernate-mapping>
<?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 package="cn.hibernate.manytomany">
<class name="Course">
<id name="cId">
<generator class="native"></generator>
</id>
<property name="content"></property>
<property name="teacher"></property>
<set name="stu" table="s_student_course">
<key column="course_id"/>
<many-to-many class="cn.hibernate.manytomany.Student" column="student_id"/>
</set>
</class>
</hibernate-mapping>
测试类
package cn.hibernate.manytomany;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class TestApp {
private SessionFactory factory = new Configuration().configure().buildSessionFactory();
@Test
public void test(){
//新建表
Session session = factory.openSession();
session.close();
}
}