第九章 關係映射 一對一關係 共享主鍵方式實現一對一
如:person與idCard
idcard中的id作為主鍵又作為一個引向person的外鍵。person作為主表,idcard作為從表。
Person:
public class Person implements Serializable{ private Integer id; private String name; private IdCard idCard; public Person() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public IdCard getIdCard() { return idCard; } public void setIdCard(IdCard idCard) { this.idCard = idCard; } }
IdCard:
public class IdCard { private Integer id; private String cardNo; private Person person; public IdCard(){ } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Person getPerson() { return person; } public String getCardNo() { return cardNo; } public void setCardNo(String cardNo) { this.cardNo = cardNo; } public void setPerson(Person person) { this.person = person; } }
Person.hbm.xml:
<hibernate-mapping> <class name="cn.framelife.hibernate.entity.Person" table="person" catalog="hibernate"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator /> </id> <one-to-one name="idCard" ></one-to-one> <property name="name" type="java.lang.String"> <column name="name" length="45" not-null="true" /> </property> </class> </hibernate-mapping>
IdCard.hbm.xml:
<hibernate-mapping> <class name="cn.framelife.hibernate.entity.IdCard" table="id_card" catalog="hibernate"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator > <param name="property">person</param> </generator> </id> <property name="cardNo" type="java.lang.String"> <column name="card_no" length="45" not-null="true" /> </property> <!-- constrained="true", 表明當前主鍵上存在一個約束--> <one-to-one name="person" constrained="true" ></one-to-one> </class> </hibernate-mapping>
增加操作:
Person person = new Person(); person.setName("zhang"); IdCard idCard = new IdCard(); idCard.setCardNo("11111111"); idCard.setPerson(person); //在保存idCard的時候會保存person session.save(idCard); //2
查詢操作:
根據主表得到從表信息。查詢主表的時候,通過一次連接查詢查出兩張表中所需要的數據。
Person person = (Person) session.get(Person.class, 1); System.out.println("-----------"); System.out.println(person.getIdCard().getCardNo());
控製台信息:
Hibernate: select person0_.id as id2_1_, person0_.name as name2_1_, idcard1_.id as id1_0_, idcard1_.card_no as card2_1_0_ from hibernate.person person0_ left outer join hibernate.id_card idcard1_ on person0_.id=idcard1_.id where person0_.id=? -------------- 11111111
根據從表得到主表信息。查詢從表的時候,是先查從表數據,在使用到主表的對象的時候,再查詢主表。
IdCard idCard = (IdCard) session.get(IdCard.class, 1); System.out.println("-----------"); System.out.println(idCard.getPerson().getName());
控製台信息:
Hibernate: select idcard0_.id as id1_0_, idcard0_.card_no as card2_1_0_ from hibernate.id_card idcard0_ where idcard0_.id=? ----------- Hibernate: select person0_.id as id2_1_, person0_.name as name2_1_, idcard1_.id as id1_0_, idcard1_.card_no as card2_1_0_ from hibernate.person person0_ left outer join hibernate.id_card idcard1_ on person0_.id=idcard1_.id where person0_.id=? zhang
one-to-one(元素)懶加載分析:
必須同時滿足下麵的三個條件時才能實現懶散加載:
1).lazy!=false (lazy缺省方式就!=false,lazy是=proxy)
2).constrained=true
3).fetch=select(fetch缺省方式即為select)
因為主表不能有constrained=true,所以主表沒有懶加載功能。能夠懶加載的對象都是被改寫過的代理對象,當相關聯的session沒有關閉時,訪問這些懶加載對象(代理對象)的屬性(getId和getClass除外)時,hibernate會初始化這些代理,當相關聯的session關閉後,再訪問懶加載的對象將會出現異常。
在根據從表得到主表信息的查詢中,查詢從對象IdCard時實現了懶加載功能,因為它隻查詢了IdCard對象,而關聯的Person對象它沒有進行查詢。在使用到Person的時候,將IdCard關聯的Person對象也進行了查詢。因為訪問這些懶加載對象(代理對象)的屬性(getId和getClass除外)時,hibernate會初始化這些代理.
在數據量過多過大的時候,不適合使用緩存時,應該使用懶加載。
最後更新:2017-04-03 18:52:06