知道了多對1關聯映照的映照原理,我們再來看1對1關聯的情況,1對1分映照有兩種實現方案:
對其中關聯的情況我們又各分為單向、雙向兩種,而對1對1,Hibernate采取one-to-one標簽進行標識。
我們拿人(Person)與身份證件(IdCard)為1對1關聯對象的示例,他們的實體關系圖為:
采取第1種方案,則Person對應數據庫表與IdCard對應數據庫表中的主鍵是逐一對應的,不需要添加過剩的字段來表示外鍵。Person關聯映照文件中的配置為:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping⑶.0.dtd">
<hibernate-mapping>
<class name="com.tgb.hibernate.Person" table="t_person">
<id name="id">
<!-- 主鍵策略foreign -->
<generator class="foreign">
<!-- property指關聯對象 -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name" />
<one-to-one name="idCard" constrained="true" />
</class>
</hibernate-mapping>
注:one-to-one標簽中的 constrained=”true”表示當前主鍵同時也是1個外鍵,參照IdCard中的主鍵。
1.調用session的Load方法,得出Person對象的級聯班級對象IdCard
public void testLoad(){
Session session = null;
Transaction tx = null;
try{
session = HibernateUtils.getSession();
tx = session.beginTransaction();
Person person = (Person)session.load(Person.class, 1);
System.out.println("person.name = " + person.getName());
System.out.println("person.idCard.cardNo = " + person.getIdCard().getCardNo());
session.save(person);
tx.commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
}
與上篇文章介紹的類似,通過one-to-one標簽的作用,我們查詢Person對象的同時,級聯查詢除IdCard對象
2.默許級聯保存Idcard機制
public void testSave(){
Session session = null;
Transaction tx = null;
try{
session = HibernateUtils.getSession();
tx = session.beginTransaction();
IdCard idCard = new IdCard();
idCard.setCardNo("11111111111");
Person person = new Person();
person.setName("張3");
person.setIdCard(idCard);
session.save(person);
tx.commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
}
上篇文章中我們提到過,在援用有Transient對象的Persistent狀態的對象進行保存時,會出現異常,但在1對1主鍵關聯映照上不會出現此種情況。也就是說,1對1默許帶有cascade屬性。對1對1主鍵關聯映照,雙向關聯的配置即是在IdCard端加入one-to-one標簽便可,此標簽僅影響加載,不影響存儲。
綜合來看將來如果改成多對1則不可修改,靈活性較差、擴大性不好。
我們可將1對1的情況看做是多對1情況的1種極端體現,我們可以采取many-to-one標簽配合unique屬性來給其相對應的表上添加外鍵字段,這類方式可解決使用主鍵關聯映照的弊端。相干映照文件以下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping⑶.0.dtd">
<hibernate-mapping>
<class name="com.tgb.hibernate.Person" table="t_person">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<many-to-one name="idCard" unique="true"></many-to-one>
</class>
</hibernate-mapping>
有關相應的操作,可參照前1篇文章的多對1下示例。
我們可以看到1對1主鍵關聯到1對1外鍵關聯的轉變可以看做是另外一種角度下看待問題,通過這樣的思想,1些本來要求刻薄的情況我們一樣可以通過另外一種方式來處理,到達相同的效果,并且實現將來變更的靈活應對。