Hibernate學(xué)習(xí)之一對(duì)一關(guān)聯(lián)
一對(duì)一關(guān)聯(lián)包括兩種類型:
1.主鍵關(guān)聯(lián)
2.惟一外鍵關(guān)聯(lián)
主鍵關(guān)聯(lián):
兩張關(guān)聯(lián)表通過主鍵形成一對(duì)一映射關(guān)系
實(shí)例:一個(gè)公民對(duì)應(yīng)一個(gè)身份證
1.主鍵關(guān)聯(lián)
實(shí)體類
TUser .java
/** * 主鍵關(guān)聯(lián) * */ public class TUser implements Serializable { private static final long serialVersionUID = -133439792227297972L; private Integer id; private Integer age; private String name; private TPassport passport; .......................... }
TPassport.java
/** * 主鍵關(guān)聯(lián) * */ public class TPassport implements Serializable{ private static final long serialVersionUID = -2207892280100301351L; private Integer id; private String serial; private Integer expiry; private TUser user; }
配置文件
Tuser.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- 主鍵關(guān)聯(lián) -->
<hibernate-mapping>
<class
name="com.model.TUser"
table="t_user"
dynamic-update="true"
>
<id
name="id"
type="java.lang.Integer"
column="id"
unsaved-value="0"
>
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="java.lang.Integer"/>
<one-to-one name="passport" class="com.model.TPassport" cascade="all" outer-join="false"/>
</class>
</hibernate-mapping>
Tpassport.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- 主鍵關(guān)聯(lián) -->
<hibernate-mapping>
<class
name="com.model.TPassport"
table="t_passport"
dynamic-update="true"
>
<id
name="id"
type="java.lang.Integer"
column="id"
unsaved-value="0"
>
<!-- 由于采用了主鍵關(guān)聯(lián)方式,那么通過主鍵關(guān)聯(lián)的兩張表,其關(guān)聯(lián)記錄的主鍵值必須保持同步。
這也就意味著,我們只需為一張表設(shè)定主鍵生成策略,而另一張表的主鍵與之共享相同的主鍵值
通過“foreign”類型的主鍵生成策略與外鍵共享主鍵值
-->
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<property name="serial" column="serial" type="string"/>
<property name="expiry" column="expiry" type="java.lang.Integer"/>
<!-- constrained必須是“true”,以告知hibernate當(dāng)前表主鍵上存在一個(gè)約束:t_passport表引用了t_user表的主鍵 -->
<one-to-one name="user" class="com.model.TUser" constrained="true"/>
</class>
</hibernate-mapping>
測(cè)試代碼(部分)
//主鍵關(guān)聯(lián) public void testSave() { TUser user = new TUser(); user.setName("zhangsan"); user.setAge(20); TPassport passport = new TPassport(); passport.setExpiry(445555); passport.setSerial("PCN2324"); // 設(shè)置相互關(guān)聯(lián) passport.setUser(user); user.setPassport(passport); try { Transaction tx = session.beginTransaction(); // 由于TUser類的one-to-one節(jié)點(diǎn)被設(shè)置為cascade=all,其關(guān)聯(lián)的passport對(duì)象將被級(jí)聯(lián)保存 session.save(user); tx.commit(); } catch (HibernateException e) { e.printStackTrace(); } } //主鍵關(guān)聯(lián) public void testLoad1() { try { TUser user = (TUser) session.load(TUser.class, 1); System.out.println("user name---->" + user.getName()); System.out.println("passport serial---->" + user.getPassport().getSerial()); } catch (HibernateException e) { e.printStackTrace(); } /** out-join="true" 加載TUser實(shí)例時(shí) hibernate通過left outer join將t_user表及其關(guān)聯(lián)的t_group表同時(shí)讀出 * Hibernate: select tuser0_.id as id1_, tuser0_.name as name1_, * tuser0_.age as age1_, tpassport1_.id as id0_, tpassport1_.serial as * serial0_, tpassport1_.expiry as expiry0_ from t_user tuser0_ * left outer join * t_passport tpassport1_ on tuser0_.id=tpassport1_.id where tuser0_.id=? */ } //主鍵關(guān)聯(lián) public void testLoad2() { try { TUser user = (TUser) session.load(TUser.class, 1); System.out.println("user name---->" + user.getName()); System.out.println("passport serial---->" + user.getPassport().getSerial()); } catch (HibernateException e) { e.printStackTrace(); } /** one-to-one節(jié)點(diǎn)設(shè)定為 out-join="false"時(shí),分別讀取 * Hibernate: select tuser0_.id as id0_, tuser0_.name as name0_, tuser0_.age as age0_ from t_user tuser0_ where tuser0_.id=? * Hibernate: select tpassport0_.id as id1_, tpassport0_.serial as serial1_, tpassport0_.expiry as expiry1_, tuser1_.id as id0_, tuser1_.name as name0_, tuser1_.age as age0_ from t_passport tpassport0_ left outer join t_user tuser1_ on tpassport0_.id=tuser1_.id where tpassport0_.id=? */ }
2.惟一外鍵關(guān)聯(lián)
實(shí)體類
TGroup.java
/** * 惟一外鍵關(guān)聯(lián)實(shí)體 */ public class TGroup implements Serializable { private static final long serialVersionUID = 263676571059714064L; private Integer id; private String name; // 不加實(shí)現(xiàn)的是單向一對(duì)一關(guān)系 通過Tuser2對(duì)象可以獲得其相對(duì)應(yīng)的Tgroup對(duì)象,但不能反過來 // 增加是為了實(shí)現(xiàn)雙向一對(duì)一關(guān)系 可以互相獲得 并且還要在TGroup.cfg.xml中追加one-to-one配置 private TUser2 user; ............................. }
TUser2.java
/** *惟一外鍵關(guān)聯(lián)實(shí)體 */ public class TUser2 implements Serializable{ private static final long serialVersionUID = -1898408468538505300L; private Integer id; private Integer age; private String name; private TGroup group; .................. }
配置文件
TGroup.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<class
name="com.model.TGroup"
table="t_group"
dynamic-update="true"
>
<id
name="id"
type="java.lang.Integer"
column="id"
unsaved-value="0"
>
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<one-to-one name="user" class="com.model.TUser2" property-ref="group"/>
</class>
</hibernate-mapping>
Tuser2.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<class
name="com.model.TUser2"
table="t_user2"
dynamic-update="true"
>
<id
name="id"
type="java.lang.Integer"
column="id"
unsaved-value="0"
>
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="java.lang.Integer"/>
<!-- 惟一外鍵關(guān)聯(lián)的一對(duì)一關(guān)系只是多對(duì)一關(guān)系的一個(gè)特例而已 -->
<many-to-one name="group" class="com.model.TGroup" column="group_id" unique="true"/>
</class>
</hibernate-mapping>
測(cè)試代碼(部分)
public void testSave2(){ TGroup group=new TGroup(); group.setName("group-one"); TUser2 user=new TUser2(); user.setName("lisi"); user.setAge(20); user.setGroup(group); try { Transaction tx=session.beginTransaction(); session.save(user); session.save(group); //必須保存 但先后順序不要求 tx.commit(); } catch (HibernateException e) { e.printStackTrace(); } } //單向 user---->group public void testLoad3(){ try { TUser2 user=(TUser2) session.load(TUser2.class, 1); System.out.println("group name--->"+user.getGroup().getName()); } catch (HibernateException e) { e.printStackTrace(); } } //雙向 group-->user public void testLoad4(){ /** * 在TGroup.cfg.xml中不添加one-to-one配置時(shí),查不到user信息 * Hibernate: select tgroup0_.id as id0_, tgroup0_.name as name0_ from t_group tgroup0_ where tgroup0_.id=? Group name---->group-one */ try { TGroup group=(TGroup) session.load(TGroup.class, 1); System.out.println("Group name---->"+group.getName()); System.out.println("group user---->"+group.getUser().getName()); } catch (HibernateException e) { e.printStackTrace(); } /** 添加配置后 * Hibernate: select tgroup0_.id as id1_, tgroup0_.name as name1_, tuser21_.id as id0_, tuser21_.name as name0_, tuser21_.age as age0_, tuser21_.group_id as group_id0_ from t_group tgroup0_ left outer join t_user2 tuser21_ on tgroup0_.id=tuser21_.group_id where tgroup0_.id=? Hibernate: select tuser20_.id as id1_, tuser20_.name as name1_, tuser20_.age as age1_, tuser20_.group_id as group_id1_, tgroup1_.id as id0_, tgroup1_.name as name0_ from t_user2 tuser20_ left outer join t_group tgroup1_ on tuser20_.group_id=tgroup1_.id where tuser20_.group_id=? Group name---->group-one group user---->lisi */ }
posted on 2011-08-23 13:35 日出星辰 閱讀(1186) 評(píng)論(0) 編輯 收藏