hibernate多對一關聯映射
關聯映射的本質:將關聯關係映射到數據庫,關聯關係在對象模型域中體現爲一個或多個引用
<many-to-one>標籤會在“多”的一端添加一個外鍵,指向“一”的一端,這個外鍵是由<many-to-one>
中的column的屬性定義的,如果忽略這個屬性,默認創建的外鍵與實體類的屬性名相同
<many-to-one>定義示例:
* <many-to-one name="group" column="groupid"/>
理解cascade
* 是對象之間的連鎖操作(只對增刪改起作用)
hibernate一對一主鍵關聯映射(單項關聯)
hibernate一對一主鍵關聯映射(單項關聯)Person--->IdCard
主鍵關聯映射:讓兩個對象的id保持相同,這樣可以避免多餘的字段被創建
<one-to-one>標籤指示hibernate如何加載其引用對象,缺省情況下根據主鍵加載其引用對象
<id name="id">
<generator class="foreign">
<!-- person中的id來源於idCard,即共享idCard主鍵 -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!-- constrained="true",當前主鍵上存在一個約束,表明person中的主鍵作爲外鍵參照了idCard -->
<one-to-one name="idCard" constrained="true"/>
hibernate一對一主鍵關聯映射(雙項關聯)
hibernate一對一主鍵關聯映射(雙項關聯)Person<--->IdCard
需要在idCard加入<one-to-one>標籤,指示hibernate如何加載person,默認情況下根據主鍵加載
<one-to-one name="person"></one-to-one>
hibernate一對一唯一外鍵關聯映射(單項關聯)
hibernate一對一唯一外鍵關聯映射(單項關聯)Person--->IdCard
一對一唯一外鍵關聯實際上是多對一關聯映射的特例
可以採用<many-to-one>標籤,指定“多”的一端unique=“true”,即限制了“多”一端的多重性爲“一”
這樣就構成了一對一唯一外鍵關聯映射
hibernate一對一唯一外鍵關聯映射(雙向關聯)
hibernate一對一唯一外鍵關聯映射(雙向關聯)Person<--->IdCard
一對一唯一外鍵雙向關聯映射,需要在另一端(IdCard),添加<one-to-one>標籤,指示hibernate如何
加載其引用對象,默認情況下根據主鍵加載person,因爲外鍵關聯映射中,兩個實體的關係是由person的
外鍵IdCard維護的,所以不能指定person的主鍵來加載person,而是根據person的外鍵idCard來加載person
對象,如:
<one-to-one name="person" property-ref="idCard"></one-to-one>
hibernate一對多關聯映射(單向關聯)
hibernate一對多關聯映射(單向關聯)Classes--->Student
這種關聯映射的原理採用的是多對一關聯映射的原理
多對一關聯映射,是在“多”的一端添加一個外鍵指向“一”的一端,它維護的關係多到一的關係
一對多關聯應是,是在“多”的一端添加一個外鍵指向“一”的一端,它維護的關係一到多的關係
也就是說,一對多和多對一關聯映射的策略是一致的,只是站的角度不同
缺點:
* 更新student表中的classesid字段時,會發出多餘的update語句,來維護classes到student之間的關係
* 如果將t_student中的classesid設置爲非空,則不能成功保存
<set name="students" order-by="id">
<!--
<key column="classesid" not-null="true"></key>
-->
<key column="classesid"></key>
<one-to-many class="com.bjsxt.hibernate.Student"/>
</set>
hibernate一對多關聯映射(雙向關聯)
hibernate一對多關聯映射(雙向關聯)Classes<--->Student
一對多雙向關聯映射的方法:
* 在“一”一端的集合中使用<key>標籤,在對方表中加入一個外鍵指向“一”一端
* 在“多"的一端採用<many-to-one>
注意:<key>標籤指定的外鍵字段必須和<many-to-one>指定的外鍵字段一致,否則引起字段錯誤
<many-to-one name="classes" column="classesid" cascade="all"></many-to-one>
如果在“一”一端維護一對多關聯關係,hibernate會發出多餘的update語句,所以我們一般在多的一端來維護關聯關係。
關於inverse屬性:
inverse主要用在一對多和多對多雙向關聯上,inverse可以被是知道集合標籤<set>上,默認inverse爲false,
所以我們可以從“一”一端和“多”一端維護關聯關係,如果設置成inverse爲true,則我們只能從多一端來維護關聯關係。
注意:inverse屬性,隻影響數據的存儲,也就是持久化
inverse和cascade
* inverse是關聯關係的控制方向
* cascade是指操作上的連鎖反映
hibernate多對多關聯映射(單項關聯)
hibernate多對多關聯映射(單項關聯)user--->role
映射規則:
<set name="roles" table="t_user_role">
<key column="userid"></key>
<many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/>
</set>
hibernate多對多關聯映射(雙項關聯)
hibernate多對多關聯映射(雙項關聯)user<--->role
映射規則:
<set name="users" table="t_user_role" order-by="userid">
<key column="roleid"/>
<many-to-many class="com.bjsxt.hibernate.User" column="userid"></many-to-many>
</set>
* table屬性值必須和單向關聯中的table屬性值一致
* <key>標籤中的column屬性值必須和單向關聯中的<many-to-many>中的column屬性值一致
* <many-to-many>標籤中的column必須和單向關聯中的<key>標籤中的column屬性值一致
基本映射說明
基本映射
類-->數據庫表
普通屬性-->表字段
通過<class>映射到數據庫表,通過<property>將普通屬性映射到表字段。
所謂普通屬性不包擴,自定義類,集合,數組
實體類主要設計原則:
* 實現一個默認的(即無參數的)構造方法(constructor)
* 提供一個標識屬性(identifier property)(可選)
* 使用非final的類(可選)
* 爲持久化字段聲明訪問器(accessors)(可選)
注意:類的名稱和屬性的名稱如果和sql中的關鍵子重複,必須用table或column重新命名
id的映射:
瞭解uuid、native和assigned
注意:類的名稱和類中屬性的名稱,如果和sql中的關鍵字重複,必須用table或column屬性重命名
hibernate的session.flush
測試session.flush
1、session在什麼情況下清理緩存:
* 默認情況下,當應用程序提交事務,如:Transaction.commit;
* 當我們顯示調用flush的時候
* 在執行某些查詢的時候,如:iterate
2、session.flush()主要完成兩件事情:
* 清理緩存
* 執行sql
3、flush執行的順序:hibernate按照save,update,delete順序提交相關操作
Hibernate的一個配置參數hibernate.hbm2ddl.auto
關鍵字: hibernate hbm2ddl.auto
Java代碼
1.<properties>
2. <property name="hibernate.show_sql" value="true" />
3. <property name="hibernate.hbm2ddl.auto" value="create" />
4.</properties>
看到了嗎?
hibernate.hbm2ddl.auto value=“create”
看一下hibernate的官方解釋:
hibernate.hbm2ddl.auto Automatically validate or export schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly. eg. validate | update | create | create-drop
有意思吧~!
竟然可以自動創建|更新|驗證數據庫表結構。
呵呵 不過如果不是此方面的需求建議set value="none".
下面是這幾個屬性的解釋:
validate 加載hibernate時,驗證創建數據庫表結構
create 每次加載hibernate,重新創建數據庫表結構,這就是導致數據庫表數據丟失的原因。
create-drop 加載hibernate時創建,退出是刪除表結構
update 加載hibernate自動更新數據庫結構
1.請慎重使用此參數,沒必要就不要隨便用。如果要用盡量使用update
2.如果發現數據庫表丟失,請檢查hibernate.hbm2ddl.auto的配置
hibernate lazy策略可以使用在:
* <class>標籤上,可以取值:true/false
* <property>標籤上,可以取值:true/false需要類增強工具
* <set><list>標籤上,可以取值:true/false/extra
* <one-to-one><many-to-one>單端關聯上,可以取值:false/proxy/noproxy
lazy概念:只有真正使用該對象時,纔會創建,對於hibernate而言,正真使用的時候纔會發出sql
hibernate支持lazy策略只有在session打開狀態下有效
<class>標籤上的lazy特性只對普通屬性起作用hibernate lazy策略可以使用在:
* <class>標籤上,可以取值:true/false
* <property>標籤上,可以取值:true/false需要類增強工具
* <set><list>標籤上,可以取值:true/false/extra
* <one-to-one><many-to-one>單端關聯上,可以取值:false/proxy/noproxy
lazy概念:只有真正使用該對象時,纔會創建,對於hibernate而言,正真使用的時候纔會發出sql
hibernate支持lazy策略只有在session打開狀態下有效
<class>標籤上的lazy特性只對普通屬性起作用
重要的概念:
1、lazy的概念,指在需要的時候才發出sql
2、lazy策略只是在session打開期間纔是有效的
注意:
Hibernate類級別的lazy加載策略:可以控制什麼時候加載這些普通對象屬性
測試單元的使用:
請先運行初時化程序InitData,在執行每個單元測試
Hibernate集合屬性的懶加載策略:
在集合屬性上,可以配置懶加載策略,取值爲:true/false/extra
true:默認取值,它的意思是只有在調用這個集合獲取裏面的元素對象時,才發出查詢語句,加載其
集合元素的數據
false:取消懶加載特性,即在加載對象的同時,就發出第二條查詢語句加載其關聯集合的數據
extra:一種比較聰明的懶加載策略,即調用集合的size/contains等方法的時候,hibernate並不會去加載整個集合的數據,而是發出一條聰明的SQL語句,以便獲得需要的值,只有在真正需要用到這些集合元素對象數據的時候,纔去發出查詢語句加載所有對象的數據
Hibernate單端關聯懶加載策略:即在<one-to-one>/<many-to-one>標籤上可以配置
懶加載策略。
可以取值爲:false/proxy/no-proxy
false:取消懶加載策略,即在加載對象的同時,發出查詢語句,加載其關聯對象
proxy:這是hibernate對單端關聯的默認懶加載策略,即只有在調用到其關聯對象的方法的時候
才真正發出查詢語句查詢其對象數據,其關聯對象是代理類
no-proxy:這種懶加載特性需要對類進行增強,使用no-proxy,其關聯對象不是代理類
注意:在class標籤上配置的lazy屬性不會影響到關聯對象!!!
hibernate的lazy策略forClass
lazy策略可以用在:
* <class>標籤上,可以取值:true/false
* <property>標籤上,可以取值:true/false,這個特性需要類增強工具
* <set><list>等集合上,可以取值:true/false/extra
* <one-to-one>和<many-to-many>(單端關聯)等標籤上,可以取值:false/proxy/noproxy
概念:
1、lazy是隻有需要的時候才發出sql語句
2、hibernate支持lazy策略,只有session打開狀態下才有效
hibernate類級別的lazy測試,可以控制什麼時候加載這些普通屬性
把class的lazy設置成false時,再load類時會把普通屬性都查出來,但是集合不查
class標籤上的lazy不會影響到集合上的lazy特性
class標籤上的lazy特性只對普通屬性起作用
使用:
1、運行initData
2、運行測試用例
hibernate在集合上的lazy策略
hibernate在集合上的lazy策略,可以取值true/false/extra
測試集合lazy:
get集合時不會發sql,迭代會發sql
查個數的時候會把整個集合查出來,這樣的話對效率有影響
lazy在集合上用extra在獲取size的時候會發出count語句,這樣對效率有提升
使用:
1、運行InitData
2、運行測試用例
hibernate在單端關聯上的lazy策略
hibernate在單端關聯上的lazy策略,<one-to-one>和<many-to-one>,可以取值:false/proxy/noproxy
在單端關聯上lazy默認,和集合一樣,在get時返回代理不發查詢語句,在使用時發出sql
在單端關聯上lazy=false,在訪問普通屬性時發出兩條sql,查詢屬性以及對應的關聯對象
將class標籤上lazy設置成false,其它默認:
不會影響單端關聯,也不會影響集合
使用:
1、運行InitData
2、運行測試用例
Hibernate中的繼承映射
Hibernate的繼承映射包含了三種不同的策略:
1.每棵繼承樹映射成一張表
2.每個子類映射成一張表;
3.每個具體類映射成一張表(有限制)。
每棵繼承樹映射成一張表
每棵繼承樹映射成一張表
t_animal
idnameSexweightheighttype
1豬豬True100P
2鳥鳥False50B
Animal.java
publicclass Animal {
privateint id;
private String name;
privateboolean sex;
getter and setter; }
Pig.java
publicclass Pig extends Animal {
privateint weight;
getter and setter;
}
Bird.java
publicclass Bird extends Animal {
privateint height;
getter and setter;
}
Extend.hbm.xml
<hibernate-mapping package="com.bjsxt.hibernate">
<class name="Animal" table="t_animal" lazy="false">
<id name="id">
<generator class="native"/>
</id>
<discriminator column="type" type="string"/>
<property name="name"/>
<property name="sex"/>
<subclass name="Pig" discriminator-value="P">
<property name="weight"/>
</subclass>
<subclass name="Bird" discriminator-value="B">
<property name="height"/>
</subclass>
</class>
</hibernate-mapping>
每個子類一個表;(效率不高。實體類跟上面的一樣)
<hibernate-mapping package="com.bjsxt.hibernate">
<class name="Animal" table="t_animal">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="sex"/>
<joined-subclass name="Pig" table="t_pig">
<key column="pid"/>
<property name="weight"/>
</joined-subclass>
<joined-subclass name="Bird" table="t_bird">
<key column="bid"/>
<property name="height"/>
</joined-subclass>
</class>
</hibernate-mapping>
每個具體類映射成一張表(主表可以不生成 在class中 設置 abstract = “ true”)
t_pig
idNamesexweight
1豬豬true100
t_bird
idNamesexheight
2鳥鳥false50
session{
map{
key=Animal+id
}
}
(實體類跟上面的一樣) 主鍵不能用自增,主鍵手動設置
Extends.hbm.xml
<hibernate-mapping package="com.bjsxt.hibernate">
<class name="Animal"abstract="true">
<id name="id">
<generator class="assigned"/>
</id>
<property name="name"/>
<property name="sex"/>
<union-subclass name="Pig" table="t_pig">
<property name="weight"/>
</union-subclass>
<union-subclass name="Bird" table="t_bird">
<property name="height"/>
</union-subclass>
</class>
</hibernate-mapping>
component映射(只建一張表)
在hibernate中,component是某個實體的邏輯組成部分,它與實體的根本區別是沒有oid,
component可以成爲是值對象(DDD)
採用component映射的好處:它實現了對象模型的細粒度劃分,層次會更分明,複用率會更高
Contact.java
publicclass Contact {
private String email;
private String address;
private String zipCode;
private String contactTel;
getter and setter;
}
User.java
publicclass User {
privateint id;
private String name;
private Contact contact;
getter and setter;
}
User.hbm.xml
<hibernate-mapping>
<class name="com.bjsxt.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<component name="contact">
<property name="email"/>
<property name="address"/>
<property name="zipCode"/>
<property name="contactTel"/>
</component>
</class>
</hibernate-mapping>
通常將複合主鍵相關的屬性,單獨放到一個類中
* 此類必須實現序列化接口
* 覆寫hashcode和equals方法
<hibernate-mapping>
<class name="com.bjsxt.hibernate.FiscalYearPeriod" table="t_fiscal_year_period">
<composite-id name="fiscalYearPeriodPK">
<key-property name="fiscalYear"/> //第一個主鍵
<key-property name="fiscalPeriod"/> //第二個主鍵
</composite-id>
<property name="beginDate"/>
<property name="endDate"/>
<property name="periodSts"/>
</class>
</hibernate-mapping>
hibernate-悲觀鎖與樂觀鎖
悲觀鎖
悲觀鎖的實現,通常依賴於數據庫機制,在整個過程中將數據鎖定,其它任何用戶都不能讀取或修改
Inventory.java
publicclass Inventory {
privateint itemNo;
private String itemName;
privateint quantity;}
<pre name="code"class="java">Inventory.hbm..xml
<hibernate-mapping>
<class name="com.bjsxt.hibernate.Inventory" table="t_inventory">
<id name="itemNo">
<generator class="native"/>
</id>
<property name="itemName"/>
<property name="quantity"/>
</class>
</hibernate-mapping></pre>操作類中實現:
<br> Inventory inv = (Inventory)session.load(Inventory.class, 1, LockMode.UPGRADE);
Hibernate的加鎖模式有:
LockMode.NONE : 無鎖機制。
LockMode.WRITE :Hibernate在Insert和Update記錄的時候會自動獲取。
LockMode.READ : Hibernate在讀取記錄的時候會自動獲取。
以上這三種鎖機制一般由Hibernate內部使用,如Hibernate爲了保證Update
過程中對象不會被外界修改,會在save方法實現中自動爲目標對象加上WRITE鎖。
LockMode.UPGRADE :利用數據庫的for update子句加鎖。
LockMode. UPGRADE_NOWAIT :Oracle的特定實現,利用Oracle的for update nowait子句實現加鎖。
樂觀鎖
大多數基於數據版本記錄機制(version)實現,一般是在數據庫表中加入一個version字段
讀取數據時將版本號一同讀出,之後更新數據時版本號加一,如果提交數據時版本號小於或等於數據表中
的版本號,則認爲數據是過期的,否則給予更新
<hibernate-mapping>
<class name="Inventory" table="t_inventory" optimistic-lock="version">
<id name="itemNo">
<generator class="native"/>
</id>
<version name="version"/>
<property name="itemName"/>
<property name="quantity"/>
</class>
</hibernate-mapping>
hibernate查詢語言hql
1、簡單屬性查詢【重要】
* 單一屬性查詢,返回結果集屬性列表,元素類型和實體類中相應的屬性類型一致
* 多個屬性查詢,返回的集合元素是對象數組,數組元素的類型和對應的屬性在實體類中的類型一致
*在hql中關鍵字不區分大小寫,但是屬性和類名區分大小寫
數組的長度取決與select中屬性的個數
* 如果認爲返回數組不夠對象化,可以採用hql動態實例化Student對象
參見:SimplePropertyQueryTest.java
2、實體對象查詢【重要】
* N + 1問題,在默認情況下,使用query.iterate查詢,有可以能出現N+1問題
所謂的N+1是在查詢的時候發出了N+1條sql語句
1: 首先發出一條查詢對象id列表的sql
N: 根據id列表到緩存中查詢,如果緩存中不存在與之匹配的數據,那麼會根據id發出相應的sql語句
* list和iterate的區別?
* list每次都會發出sql語句,list會向緩存中放入數據,而不利用緩存中的數據
* iterate:在默認情況下iterate利用緩存數據,但如果緩存中不存在數據有可以能出現N+1問題
參見:SimpleObjectQueryTest1.java/SimpleObjectQueryTest2.java
3、條件查詢【重要】
* 可以採用拼字符串的方式傳遞參數
* 可以採用 ?來傳遞參數(索引從0開始)
* 可以採用 :參數名 來傳遞參數
* 如果傳遞多個參數,可以採用setParamterList方法
* 在hql中可以使用數據庫的函數,如:date_format
參見:SimpleConditionQueryTest.java
4、hibernate也支持直接使用sql進行查詢
參見:SqlQueryTest.java
5、外置命名查詢
* 在映射文件中採用<query>標籤來定義hql
* 在程序中採用session.getNamedQuery()方法得到hql查詢串
參見:Student.hbm.xml、NameQueryTest.java
6、查詢過濾器
* 在映射文件中定義過濾器參數
* 在類的映射中使用這些參數
* 在程序中啓用過濾器
參見:Student.hbm.xml、FilterQueryTest.java
7、分頁查詢【重要】
* setFirstResult(),從0開始
* setMaxResults,每頁顯示多少條數據
參見:PageQueryTest.java
8、對象導航查詢,在hql中採用 . 進行導航【重要】
參見:ObjectNavQueryTest.java
9、連接查詢【重要】
* 內連
* 外連接(左連接/右連接)
參見:JoinQueryTest.java
10、統計查詢【重要】
參見:StatQueryTest.java
11、DML風格的操作(儘量少用,因爲和緩存不同步)
參見:DMLQueryTest.java
hibernate一級緩存
一級緩存很短和session的生命週期一致,一級緩存也叫session級的緩存或事務級緩存
那些方法支持一級緩存:
* get()
* load()
* iterate(查詢實體對象)
如何管理一級緩存:
* session.clear(),session.evict()
如何避免一次性大量的實體數據入庫導致內存溢出
* 先flush,再clear
如果數據量特別大,考慮採用jdbc實現,如果jdbc也不能滿足要求可以考慮採用數據本身的特定導入工具
在同一個session中發出兩次load查詢:
Student student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());
//不會發出sql,因爲load使用緩存
student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());
在同一個session中發出兩次get查詢:
Student student = (Student)session.get(Student.class, 1);
System.out.println("student.name=" + student.getName());
//不會發出sql,因爲get使用緩存
student = (Student)session.get(Student.class, 1);
System.out.println("student.name=" + student.getName());
在同一個session中發出兩次iterate查詢實體對象:
Student student =
(Student)session.createQuery("from Student s where s.id=1").iterate().next();
System.out.println("student.name=" + student.getName());
//會發出查詢id的sql,不會發出查詢實體對象的sql,因爲iterate使用緩存
student =
(Student)session.createQuery("from Student s where s.id=1").iterate().next();
System.out.println("student.name=" + student.getName());
String name =
(String)session.createQuery("select s.name from Student s where s.id=1").iterate().next();
System.out.println("student.name=" + name);
//iterate查詢普通屬性,一級緩存不會緩存,所以發出sql
//一級緩存是緩存實體對象的
name =
(String)session.createQuery("select s.name from Student s where s.id=1").iterate().next();
System.out.println("student.name=" + name);
Session1中:
session = HibernateUtils.getSession();
session.beginTransaction();
Student student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());
Session2中:
//會發出查詢語句,session間不能共享一級緩存的數據
//因爲它會伴隨session的生命週期存在和消亡
Student student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());
在同一個session中先save,在發出load查詢save過的數據:
Student stu = new Student();
stu.setName("王五");
Serializable id = session.save(stu);
//不會發出sql,因爲save是使用緩存的
Student student = (Student)session.load(Student.class, id);
System.out.println("student.name=" + student.getName());
向數據庫中批量加入1000條數據:
for (int i=0; i<1000; i++) {
Student student = new Student();
student.setName("s_" + i);
session.save(student);
//每20條數據就強制session將數據持久化
//同時清除緩存,避免大量數據造成內存溢出
if ( i % 20 == 0) {
session.flush();
session.clear();
}
}
hibernate二級緩存
二級緩存也稱進程級的緩存或SessionFactory級的緩存,二級緩存可以被所有的session共享
二級緩存的生命週期和SessionFactory的生命週期一致,SessionFactory可以管理二級緩存
二級緩存的配置和使用:
* 將echcache.xml文件拷貝到src下
* 開啓二級緩存,修改hibernate.cfg.xml文件
<property name="hibernate.cache.use_second_level_cache">true</property>
* 指定緩存產品提供商,修改hibernate.cfg.xml文件
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
* 指定那些實體類使用二級緩存(兩種方法)
* 在映射文件中採用<cache>標籤
* 在hibernate.cfg.xml文件中,採用<class-cache>標籤
二級緩存是緩存實體對象的
瞭解一級緩存和二級緩存的交互
Hibernate.cfg.xml
<!-- 開啓二級緩存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 指定緩存產品提供商 -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvide
r</property>
hibernate查詢緩存
查詢緩存是針對普通屬性結果集的緩存
對實體對象的結果集只緩存id
查詢緩存的生命週期,當前關聯的表發生修改,那麼查詢緩存生命週期結束
查詢緩存的配置和使用:
* 在hibernate.cfg.xml文件中啓用查詢緩存,如:
<property name="hibernate.cache.use_query_cache">true</property>
* 在程序中必須手動啓用查詢緩存,如:
query.setCacheable(true);
hibernate抓取策略(單端代理的批量抓取)
保持默認,同fetch="select",如:
<many-to-one name="classes" column="classesid" fetch="select"/>
fetch="select",另外發送一條select語句抓取當前對象關聯實體或集合
hibernate抓取策略(單端代理的批量抓取)
設置fetch="join",如:
<many-to-one name="classes" column="classesid" fetch="join"/>
fetch="join",hibernate會通過select語句使用外連接來加載其關聯實體或集合
此時lazy會失效
hibernate抓取策略(集合代理的批量抓取)
保持默認,同fetch="select",如:
<set name="students" inverse="true" cascade="all" fetch="select">
fetch="select",另外發送一條select語句抓取當前對象關聯實體或集合
hibernate抓取策略(集合代理的批量抓取)
設置fetch="join",如:
<set name="students" inverse="true" cascade="all" fetch="join">
fetch="join",hibernate會通過select語句使用外連接來加載其關聯實體或集合
此時lazy會失效
hibernate抓取策略(集合代理的批量抓取)
設置fetch="subselect",如:
<set name="students" inverse="true" cascade="all" fetch="subselect">
fetch="subselect",另外發送一條select語句抓取在前面查詢到的所有實體對象的關聯集合
hibernate抓取策略,,batch-szie在<class>上的應用
batch-size屬性,可以批量加載實體類,參見:Classes.hbm.xml
<class name="Classes" table="t_classes" batch-size="3">
hibernate抓取策略,batch-szie在集合上的應用
batch-size屬性,可以批量加載實體類,參見:Classes.hbm.xml
<set name="students" inverse="true" cascade="all" batch-size="5">