關於hibernate的載入方式有兩種,一種是get載入,一種是load載入,load屬於消極式載入,使用了動態代理。這不是我們所關心的,我們看一看一對一雙向關聯在載入時有什麼特點,想要觀察特點,不得不看hibernate為我們產生的sql語句。
husband類與上一篇沒有變化如下:
/** * */package com.maybe.test_1;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;import javax.persistence.Table;/** * @author MayBe * * function: */@Entity@Table(name="t_husband")public class Husband {private Integer id;private String name;private Wife wife;@Id@GeneratedValuepublic Integer getId() {return id;}public String getName() {return name;}public void setId(Integer id) {this.id = id;}public void setName(String name) {this.name = name;}@OneToOne(mappedBy="husband")public Wife getWife() {return wife;}public void setWife(Wife wife) {this.wife = wife;}}
wife類也沒有變化:
/** * */package com.maybe.test_1;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.Table;/** * @author MayBe * * function: */@Entity@Table(name="t_wife")public class Wife {private Integer id;private String name;private Husband husband;@Id@GeneratedValuepublic Integer getId() {return id;}public String getName() {return name;}public void setId(Integer id) {this.id = id;}public void setName(String name) {this.name = name;}@OneToOnepublic Husband getHusband() {return husband;}public void setHusband(Husband husband) {this.husband = husband;}}
junit測試方法如下:
@Testpublic void One_to_oneLoadTest1(){//一對一雙向關聯Session s = sessionFacotry.getCurrentSession();s.beginTransaction();Husband hus = (Husband)s.get(Husband.class, 2); System.out.println("*****************");Wife wif = (Wife)s.get(Wife.class, 3);s.getTransaction().commit();}
假設我們在資料中存在一個id為2的husband,他與id為2的wife是關聯的。在資料庫有一個id為3的wife,她與id為3的husband是關聯的,我們運行一下這個測試,輸出sql語句如下:
2014-02-04 16:52:20 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:182 - HHH000228: Running hbm2ddl schema update 2014-02-04 16:52:20 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:193 - HHH000102: Fetching database metadata 2014-02-04 16:52:20 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:205 - HHH000396: Updating schema 2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_husband 2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, name] 2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: [] 2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_husban__3213e83f0f624af8] 2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_wife 2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, husband_id, name] 2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: [fk_fi3kodkmubgryyblf4935y4dk] 2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_wife__3213e83f1332dbdc] 2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:242 - HHH000232: Schema update complete Hibernate: select husband0_.id as id1_0_0_, husband0_.name as name2_0_0_, wife1_.id as id1_1_1_, wife1_.husband_id as husband_3_1_1_, wife1_.name as name2_1_1_ from t_husband husband0_ left outer join t_wife wife1_ on husband0_.id=wife1_.husband_id where husband0_.id=?*****************Hibernate: select wife0_.id as id1_1_0_, wife0_.husband_id as husband_3_1_0_, wife0_.name as name2_1_0_, husband1_.id as id1_0_1_, husband1_.name as name2_0_1_ from t_wife wife0_ left outer join t_husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.id=?Hibernate: select wife0_.id as id1_1_1_, wife0_.husband_id as husband_3_1_1_, wife0_.name as name2_1_1_, husband1_.id as id1_0_0_, husband1_.name as name2_0_0_ from t_wife wife0_ left outer join t_husband husband1_ on wife0_.husband_id=husband1_.id where wife0_.husband_id=?
首先載入husband對象時會把相關聯的欄位全部載入出來。
但是可以看出來載入wife表的時候會執行兩次查詢,雖然這兩次查詢的內容是一樣的,但是第一次是查詢出的是主表的資訊,第二次是為了查出從表資訊,這是hibernate的預設載入策略,因為t_wife表有外鍵,如果載入的表有從表,他會預設載入同時夾在兩個表的資訊。是否載入從表資訊是由fetch進行設定的。
我們把wife類one-to-one新添加一個屬性
/** * */package com.maybe.test_1;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.Table;/** * @author MayBe * * function: */@Entity@Table(name="t_wife")public class Wife {private Integer id;private String name;private Husband husband;@Id@GeneratedValuepublic Integer getId() {return id;}public String getName() {return name;}public void setId(Integer id) {this.id = id;}public void setName(String name) {this.name = name;}@OneToOne(fetch=FetchType.LAZY)public Husband getHusband() {return husband;}public void setHusband(Husband husband) {this.husband = husband;}}
我們把抓取方式改成懶抓取,載入輸出如下所示:
2014-02-04 17:07:38 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:182 - HHH000228: Running hbm2ddl schema update
2014-02-04 17:07:38 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:193 - HHH000102: Fetching database metadata
2014-02-04 17:07:38 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:205 - HHH000396: Updating schema
2014-02-04 17:07:39 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_husband
2014-02-04 17:07:39 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, name]
2014-02-04 17:07:39 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: []
2014-02-04 17:07:39 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_husban__3213e83f0f624af8]
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_wife
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, husband_id, name]
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: [fk_fi3kodkmubgryyblf4935y4dk]
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_wife__3213e83f1332dbdc]
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:242 - HHH000232: Schema update complete
Hibernate:
select
husband0_.id as id1_0_0_,
husband0_.name as name2_0_0_,
wife1_.id as id1_1_1_,
wife1_.husband_id as husband_3_1_1_,
wife1_.name as name2_1_1_
from
t_husband husband0_
left outer join
t_wife wife1_
on husband0_.id=wife1_.husband_id
where
husband0_.id=?
*****************
Hibernate:
select
wife0_.id as id1_1_0_,
wife0_.husband_id as husband_3_1_0_,
wife0_.name as name2_1_0_
from
t_wife wife0_
where
wife0_.id=?
這樣wife類只載入自己主表的資訊,不考慮從表的資訊了( 當然把husband也是如此,可以自己去試試)。
hibernate預設的載入策略為eager載入,也就是急抓取,會把所關聯的資訊一次性全部得到,而lazy則都是在你用到從表才會去載入。
我們改變一下測試類別內容:
public void One_to_oneLoadTest1() {// 一對一雙向關聯Session s = sessionFacotry.getCurrentSession();s.beginTransaction();Husband hus = (Husband) s.get(Husband.class, 2); System.out.println("*****************");Wife wif = (Wife) s.get(Wife.class, 3);System.out.println(wif.getHusband().getName());s.getTransaction().commit();}
輸出如下:
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:182 - HHH000228: Running hbm2ddl schema update
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:193 - HHH000102: Fetching database metadata
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:205 - HHH000396: Updating schema
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_husband
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, name]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: []
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_husban__3213e83f0f624af8]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_wife
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, husband_id, name]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: [fk_fi3kodkmubgryyblf4935y4dk]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_wife__3213e83f1332dbdc]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:242 - HHH000232: Schema update complete
Hibernate:
select
husband0_.id as id1_0_0_,
husband0_.name as name2_0_0_,
wife1_.id as id1_1_1_,
wife1_.husband_id as husband_3_1_1_,
wife1_.name as name2_1_1_
from
t_husband husband0_
left outer join
t_wife wife1_
on husband0_.id=wife1_.husband_id
where
husband0_.id=?
*****************
Hibernate:
select
wife0_.id as id1_1_0_,
wife0_.husband_id as husband_3_1_0_,
wife0_.name as name2_1_0_
from
t_wife wife0_
where
wife0_.id=?
Hibernate:
select
husband0_.id as id1_0_0_,
husband0_.name as name2_0_0_,
wife1_.id as id1_1_1_,
wife1_.husband_id as husband_3_1_1_,
wife1_.name as name2_1_1_
from
t_husband husband0_
left outer join
t_wife wife1_
on husband0_.id=wife1_.husband_id
where
husband0_.id=?
Hibernate:
select
wife0_.id as id1_1_0_,
wife0_.husband_id as husband_3_1_0_,
wife0_.name as name2_1_0_
from
t_wife wife0_
where
wife0_.husband_id=?
GossipMan
這樣才會載入從表的資訊,對於一些其他的語句,可能是hibernate自動產生的其他語句,但只要理解其中的思想就可以了,不要在意這些細節。