1、整理思路:html
以前,小編總結過Mybatis的關聯映射,接下來,再來總結一下hibernate的相關的關聯映射,直接上圖:java
這張圖,就是小編整理總結整個Hibernate的關聯映射的一個大體思路。sql
2、名詞解釋「session
一、單向關聯:很簡單,就是一個對象依賴於另外一個對象。app
二、雙向關聯:兩個對象互相依賴。ssh
3、一對一(one-to-one)關聯映射:oop
所謂的一對一,大白話理解就是一個物件擁有的某種附屬物件能並且只能擁有一件。舉個例子就是做爲學生,一個學生只能擁有一個有效的學生證,一個堂堂正正的中國公民也只能擁有一張有效的身份證。這就是一對一。接下來,咱們就利用在職學生爲例,說一下一對一映射。測試
在Hibernate中有兩種方式能實現一對一映射,分別是:fetch
一、主鍵關聯;this
二、惟一外鍵關聯。
4、逐一介紹:
4.一、一對一單向關聯映射
4.1.一、一對一單向關聯映射——主鍵關聯
核心:一個對象依賴於另外一個對象。舉例:根據學生,找到對應的有效學生證。
Po對象設計:
StudentCard.Java:
- public class StudentCard{
- private int id;
- private String cardNo;
-
- }
Student.java:
- public class Student{
- private int id;
- private String name;
- private StudentCard studentCard;
-
- }
映射文件:
StudentCard.hbm.xml
- <hibernate-mapping package="org.hibernate.test" >
- <class name="com.ssh.hibernate.StudentCard" table="t_studentCard">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="cardNo"/>
- </class>
- </hibernate-mapping>
Student.hbm.xml
- <hibernate-mapping package="org.hibernate.test" >
- <class name="com.ssh.hibernate.Person" table="t_student">
- <id name="id" type="int">
- <generator class="foreign">
- <param name="property">studentCard</param>
- </generator>
- </id>
- <one-to-one name="studentCard" constrained="true"/>
- <property name="name"/>
- </class>
- </hibernate-mapping>
分析:核心<one-to-one name="studentCard" constrained="true"/>,表示一個Student對應一個StudentCard。constrained=」true」表示t_student表的主鍵上同時有個外鍵指向被關聯的表(t_studentCard)的主鍵,會對錶t_student建立約束,約束t_student的id只能跟studentCard的主鍵同樣,也就是說,Student上的id既是主鍵也是外鍵。
測試:
- session.beginTransaction();
- StudentCard studentCard=new StudentCard();
- studentCard.setCardNo("12050242013");
- Student student=new Student();
- student.setName("Davie");
- person.setstudentCard(student);
- session.save(person);
- session.getTransaction().commit();
這時,會先插入一條StudentCard信息,而後再插入Student信息:
- insert into t_studentCard (cardNo) values (?)
- insert into t_student (name, id) values (?, ?)
4.2.二、一對一單向關聯映射——惟一外鍵關聯
核心:惟一外鍵關聯,就是給一對一關聯關係中某個對象加一個外鍵。舉例:給Student表添加一個外鍵,指向StudentCard的主鍵,並且外鍵惟一,這樣也就達到了一對一映射的效果。
Po對象設計:
StudentCard.java:
- public class StudentCard{
- private int id;
- private String cardNo;
-
- }
Student.java:
- public class Student{
- private int id;
- private String name;
- private StudentCard studentCard;
-
- }
映射文件:
StudentCard.hbm.xml
- <hibernate-mapping package="org.hibernate.test" >
- <class name="com.ssh.hibernate.StudentCard" table="t_studentCard">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="cardNo"/>
- </class>
- </hibernate-mapping>
Student.hbm.xml
- <hibernate-mapping package="org.hibernate.test" >
- <class name="com.ssh.hibernate.Person" table="t_student">
- <id name="id" type="int">
- <generator class="foreign">
- <param name="property">studentCard</param>
- </generator>
- </id>
- <many-to-one name="studentCard" unique="true"/>
- <property name="name"/>
- </class>
- </hibernate-mapping>
分析:
這裏與主鍵關聯還有點不同,t_student的主鍵生成策略是native,再也不以未見形式關聯到t_studentCard的主鍵,用<many-to-one>標籤與t_idcard創建多對一的關係,這樣就能夠在t_student中生成一個外鍵關聯到t_studentCard的主鍵。
這時候若是還用上面的測試代碼進行測試,就會報錯:「org.hibernate.TransientObjectException: object references an unsaved transient instance」
由於t_student的主鍵生成策略是native,和t_studentCard無關,而studentCard並無變成TransientObject,因此,咱們必需要先將studentCard變成持久化對象:
- session.beginTransaction();
- StudentCard studentCard=new StudentCard();
- studentCard.setCardNo("12050242013");
- session.save(studentCard);
- Student student=new Student();
- student.setName("Davie");
- person.setstudentCard(student);
- session.save(person);
- session.getTransaction().commit();
4.二、一對一雙向關聯映射
4.2.1一對一雙向關聯映射——主鍵關聯
核心:兩個對象之間,相互依賴
Po對象
StudentCard.java
- public class StudentCard{
- private int id;
- private String cardNo;
- private Student student;
-
- }
Student.java
- public class Student{
- private int id;
- private String name;
- private StudentCard studentCard;
-
- }
配置文件:
StudentCard.hbm.xml
- <hibernate-mapping package="org.hibernate.test" >
- <class name="com.ssh.hibernate.StudentCard" table="t_studentCard">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="cardNo"/>
- <one-to-one name="student" fetch="join">
- </class>
- </hibernate-mapping>
Student.hbm.xml
- <hibernate-mapping package="org.hibernate.test" >
- <class name="com.ssh.hibernate.Person" table="t_student">
- <id name="id" type="int">
- <generator class="foreign">
- <param name="property">studentCard</param>
- </generator>
- </id>
- <one-to-one name="studentCard" constrained="true"/>
- <property name="name"/>
- </class>
- </hibernate-mapping>
測試如上,咱們查出Student時,Student.studentCard能夠獲取學生證信息。當咱們查出StudentCard時,StudentCard.student能夠獲取學生信息。可是也正是由於他們之間是這種關係,沒有相互的約束,因此當咱們執行:
- session.beginTransaction();
- Student student=new Student();
- student.setName("Davie");
- StudentCard studentCard=new StudentCard();
- studentCard.setCardNo("12050242013");
- studentCard.setPerson(person);
- session.save(studentCard);
- session.getTransaction().commit();
session只會save(studentCard),而不會save(student);
4.2.2一對一雙向關聯映射——惟一外鍵關聯
直接上配置了:
Po對象設計:
StudentCard.java
- public class StudentCard{
- private int id;
- private String cardNo;
- private Student student;
-
- }
Student.java
- public class Student{
- private int id;
- private String name;
- private StudentCard studentCard;
-
- }
配置文件:
StudentCard.hbm.xml
- <hibernate-mapping package="org.hibernate.test" >
- <class name="com.ssh.hibernate.StudentCard" table="t_studentCard">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="cardNo"/>
- <one-to-one name="student" property-ref="studentCard">
- </class>
- </hibernate-mapping>
Student.hbm.xml
- <hibernate-mapping package="org.hibernate.test" >
- <class name="com.ssh.hibernate.Person" table="t_student">
- <id name="id" type="int">
- <generator class="foreign">
- <param name="property">studentCard</param>
- </generator>
- </id>
- <one-to-one name="studentCard" constrained="true"/>
- <property name="name"/>
- </class>
- </hibernate-mapping>
一張身份證只對應一位公民,因此用<one-to-one>標籤,property-ref="studentCard"指t_studentCard的主鍵與t_student中的studentCard字段對應。
到此,關於一對一映射的相關知識告一段落,可是你們要知道,惟一外鍵關聯其實就是多對一關聯的一種特殊狀況,因此當咱們需求變了,要求有一對一變成多對一的時候,咱們該怎麼辦呢?其實很簡單,直接把外鍵惟一的約束幹掉就能夠了,是否是方便不少呢?