hibernate中一對一關係看起來簡單,其實也挺複雜的。其中關係就包含了四種,單向雙向和主鍵關聯外鍵關聯。 什麼意思呢,也就是包含了單向一對一主鍵關聯、雙向一對一主鍵關聯,單向一對一外鍵關聯.
因爲一對一的主鍵關聯映射擴展性不好,當我們的需要發生改變想要將其變爲一對多的時候變無法操作了,所以我們遇到一對一關聯的時候經常會採用唯一外鍵關聯來解決問題,而很少使用一對一主鍵關聯。
所以現在就說一下基於外鍵的雙向一對一.一對一其實是多對一的一種特殊形式,就是在多的一段加入unique=”true”屬性,這樣就限制了多的一端的多重性變爲唯一.
一.思路分析
人和身份證信息是一對一的.雙向就是既可以根據Person找到對應的Card;也可以通過Card找到相應的Person.
如圖所示:
二.實體類的編寫
Person.java
public class Person {
private Integer personId;
private String personName;
private Card card;
(以及相應的set . get方法)
}
Card.java
public class Card {
private Integer cardId;
private Integer cardNum;
private Person person;
(以及相應的get .set方法)
}
三.映射文件(*.hbm.xml)
Person.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="com.qiushiju.model">
<class name="Person" table="person">
<id name="personId" column="person_id">
<generator class="native" />
</id>
<property name="personName" column="person_name" />
<!-- 雖然是一對一,但是這裏用了many-to-one,但是指定多的一端的unique=true,這樣就限制了多端的多重性爲一
name:對前持久化類中的所關聯對象的屬性
column:當前持久化類中的所關聯對象在本表(person)的外鍵(即關聯表(card)的主鍵) -->
<many-to-one name="card" column="card_id" unique="true"></many-to-one>
</class>
</hibernate-mapping>
Card.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="com.qiushiju.model">
<class name="Card" table="card">
<id name="cardId" column="card_id">
<generator class="native" />
</id>
<property name="cardNum" column="card_num" />
<!-- 一對一標籤,
name:當前持久化類所關聯對象的屬性
property-ref:這是必須的屬性,是指定所關聯類(Person)中的相對應的屬性名
-->
<one-to-one name="person" property-ref="card"></one-to-one>
</class>
</hibernate-mapping>
四.把映射文件注入配置文件中hibernate.cfg.xml
<mapping resource="Person.hbm.xml" />
<mapping resource="Card.hbm.xml" />
五.測試
添加.測試添加一個人,和相應的id
public class TestOneToOne {
public static void main(String[] args) {
//讀取cfg.xml文件
Configuration configuration = new Configuration().configure();
//建立sessionFactory
SessionFactory factory = configuration.buildSessionFactory();
//取得session
Session session = factory.openSession();
session.beginTransaction();
//創建人物
Person person = new Person();
person.setPersonName("趙雪麗");
//創建Card
Card card = new Card();
card.setCardNum(987654321);
//設置關聯
person.setCard(card);
//保存
// ① session.save(card);
session.save(person);
session.getTransaction().commit();
注意上面①處,如上面的兩個映射文件的配置的話,註釋需要打開(即同時保存兩個)才能同時保存成功.
但是在Person.hbm.xml中的下面代碼中加入級聯屬性cascade爲all或者save-update就可註釋掉①處,只保存一個對象,就可以同時保存兩張表的數據
<many-to-one name="card" column="card_id" unique="true" cascade="all"></many-to-one>
測試結果:
(第一行數據是本人自己測試時添加的)
雙向查詢測試
//通過Person對象找Card
Person p1 = (Person) session.get(Person.class, 1);
System.out.println("--->"+p1.getCard().getCardNum());
//通過Card對象找Person
Card card = (Card) session.get(Card.class, 1);
System.out.println("--->"+card.getPerson().getPersonName());
輸出結果:
—>123456789
—>邱世舉
參考文章:
http://blog.csdn.net/huangaigang6688/article/details/7761310#comments
http://www.cnblogs.com/whgk/p/6128395.html
http://blog.csdn.net/lm709409753/article/details/51038889#comments