Hibernate5入门(四)映射之一对一

目录

一、一对一主键关联(双向)

1.1 教师实体类Teacher.java

1.3 教师映射文件Teacher.hbm.xml

1.4 学生映射文件Student.hbm.xml

1.5 测试类

二、一对一外键关联(双向)

2.1 实体类

2.2 教师映射文件Teacher.hbm.xml

2.3 学生映射文件Student.hbm.xml

三、总结

3.1 映射文件的主要差别


学习笔记,为了加强记忆和深入理解在此记录备忘。如有错误和理解不当之处,还望指正。万分感谢!

另外,实例和内容有些是参照网络其他博文,如有侵权可联系删除。

参考博文:https://www.cnblogs.com/biehongli/p/6561690.html

学习重点:

1、一对一主键关联和外键关联


一对一有单向和双向、主键关联外键关联之分,在前面(一对多)已经介绍过单向和双向的区别,所以这里不再描述单向和双向。

以教师和学生为例:

    假设一个老师教一个学生知识;

    假设一个学生向一个老师学习;

一、一对一主键关联(双向)

什么是主键关联:以老师为主,学生编号既是自己的主键同时是教师编号的外键;这样导致老师可以不教学生,但是学生必须向一个老师学习,这也是主外键的约束。

1.1 教师实体类Teacher.java

package demo.entity;

public class Teacher {

	private int teaId;
	private String teaName;
	// 引入学生对象
	private Student student;
	
	public int getTeaId() {
		return teaId;
	}
	public void setTeaId(int teaId) {
		this.teaId = teaId;
	}
	public String getTeaName() {
		return teaName;
	}
	public void setTeaName(String teaName) {
		this.teaName = teaName;
	}
	public Student getStudent() {
		return student;
	}
	public void setStudent(Student student) {
		this.student = student;
	}
	
}

1.2 学生实体类Student.java

package demo.entity;

public class Student {

	private int stuId;
	private String stuName;
	// 引入教师对象
	private Teacher teacher ;
	
	public int getStuId() {
		return stuId;
	}
	public void setStuId(int stuId) {
		this.stuId = stuId;
	}
	public String getStuName() {
		return stuName;
	}
	public void setStuName(String stuName) {
		this.stuName = stuName;
	}
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	
}

1.3 教师映射文件Teacher.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-7-27 11:16:28 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <class name="demo.entity.Teacher" table="t_teacher">
        <id name="teaId" type="int">
            <column name="teaId" />
            <generator class="native" />
        </id>
        <property name="teaName" type="java.lang.String">
            <column name="teaName" />
        </property>
        <!-- name:是实体类中引入的属性名 -->
        <one-to-one name="student" class="demo.entity.Student" />
    </class>
</hibernate-mapping>

1.4 学生映射文件Student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-7-27 11:16:28 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <class name="demo.entity.Student" table="t_student">
        <id name="stuId" type="int" column="stuId">
            <!-- 重点在这里。 因为主键跟外键是同一个,所以直接在这里申明该主键就是外键 -->
            <generator class="foreign">
	            <!-- 外键指向申明的对象teacher -->
	            <param name="property">teacher</param>
            </generator>
        </id>
        <property name="stuName" type="java.lang.String">
            <column name="stuName" />
        </property>
        <!-- 一对一配置,name是实体类申明的属性-->
        <one-to-one name="teacher" class="demo.entity.Teacher" />
    </class>
</hibernate-mapping>

1.5 测试类

package demo.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import demo.entity.Student;
import demo.entity.Teacher;

class JunitTest {
	private Configuration configuration = new Configuration().configure();
	private SessionFactory sFactory = configuration.buildSessionFactory();
	private Session session = null;
	private Transaction transaction = null;
	@BeforeEach
	void setUp() throws Exception {
		session = sFactory.openSession();
		transaction = session.beginTransaction();
	}

	@AfterEach
	void tearDown() throws Exception {
		transaction.commit();
		session.close();
	}
	
	@Test
	void testSave() {
		Teacher teacher = new Teacher();
		teacher.setTeaName("老师1");
		Student student = new Student();
		student.setStuName("学生1");
		
		student.setTeacher(teacher);
		session.save(teacher);
		session.save(student);
		
	}

}

二、一对一外键关联(双向)

外键关联是多对一的特例,相对于主键关联学生在数据库表中多出一个老师编号的字段,它是老师编号的外键。

2.1 实体类

    和主键关联的实体类一样,主要区别是在映射文件

2.2 教师映射文件Teacher.hbm.xml

和主键关联的区别是:新增property-ref属性。

如果没有指定会使用对方关联类的主键来跟本类的主键比较,这里要注意不是关联表中的外键字段名,是对象属性。

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-7-27 11:16:28 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <class name="demo.entity.Teacher" table="t_teacher">
        <id name="teaId" type="int">
            <column name="teaId" />
            <generator class="native" />
        </id>
        <property name="teaName" type="java.lang.String">
            <column name="teaName" />
        </property>
        <!-- 
        	name:是实体类中引入的属性名 
        	property-ref:指定关联类的属性名(学生中申明的老师对象),
        	这个属性将会和本类的主键相对应
        -->
        <one-to-one name="student" class="demo.entity.Student" property-ref="teacher" />
    </class>
</hibernate-mapping>

2.3 学生映射文件Student.hbm.xml

这里和主键关联的区别是:主键策略正常配置,one-to-one改为many-to-one。

另外这里需要注意保存顺序,先保存主的一方(教师),可以减少update。

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-7-27 11:16:28 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <class name="demo.entity.Student" table="t_student">
        <id name="stuId" type="int" column="stuId">
            <!-- 正常配置 -->
            <generator class="native" />
        </id>
        <property name="stuName" type="java.lang.String">
            <column name="stuName" />
        </property>
        <!-- 
        	一对一配置,name是实体类申明的属性
        	column是数据库外键字段名
        	由于是多对一的特例,所以需要加unique属性        
        -->
        <many-to-one name="teacher" class="demo.entity.Teacher" 
        	column="teaId" unique="true" />
    </class>
</hibernate-mapping>

三、总结

3.1 映射文件的主要差别

属性 主键关联 外键关联
主键策略 正常配置

<id name="stuId" 
    type="int" 
    column="stuId">
    <generator class="foreign">
        <param name="property">teacher</param>
    </generator>
</id>

使用foriegn,并且param指定主键

正常配置 正常配置
对应关系

<one-to-one name="student"     class="demo.entity.Student" />

一对一正常配置

<one-to-one name="student" 
    class="demo.entity.Student" />

一对一正常配置

<one-to-one name="student" 
 class="demo.entity.Student" 
    property-ref="teacher" />

指定property-ref属性(必须)

<many-to-one name="teacher" 
 class="demo.entity.Teacher" 
    column="teaId" unique="true" />

使用many-to-one指定unique

猜你喜欢

转载自blog.csdn.net/u012423685/article/details/81222041
今日推荐