Hibernate懶/急加載示例

這篇文章將重點討論為什么以及如何在應用程序中使用稱為LAZY和EAGER加載的概念,以及如何使用Spring的休眠模板以EAGER方式加載LAZY實體。

當然,正如標題本身所暗示的那樣,我們將通過一個示例來說明這一點。 場景就是這樣;

您是一個有很多玩具的孩子的父母。 但是當前的問題是,只要您打電話給他(我們假設您有一個男孩),他也會帶著所有玩具來找您。 現在這是一個問題,因為您不希望他一直都隨身攜帶玩具。

因此,作為理論上的父母,您會繼續前進,并將孩子的玩具定義為LAZY。 現在,每當您打電話給他時,他都會不帶玩具來到您身邊。

但是您面臨另一個問題。 當需要進行家庭旅行時,您希望他帶上他的玩具,因為否則孩子會厭倦這次旅行。 但是,由于您對孩子的玩具嚴格執行LAZY,因此您無法要求他隨身攜帶玩具。 這是EAGER提取起作用的地方。 首先讓我們看看我們的領域類。

package com.fetchsample.example.domain;import java.util.HashSet;
import java.util.Set;import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;/*** Holds information about the child* * @author dinuka.arseculeratne* */
@Entity
@Table(name = 'CHILD')
@NamedQuery(name = 'findChildByName', query = 'select DISTINCT(chd) from Child chd left join fetch chd.toyList where chd.childName=:chdName')
public class Child {public static interface Constants {public static final String FIND_CHILD_BY_NAME_QUERY = 'findChildByName';public static final String CHILD_NAME_PARAM = 'chdName';}@Id@GeneratedValue(strategy = GenerationType.AUTO)/*** The primary key of the CHILD table*/private Long childId;@Column(name = 'CHILD_NAME')/*** The name of the child*/private String childName;@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)/*** The toys the child has. We do not want the child to have the same toy more than* once, so we have used a set here.*/private Set<Toy> toyList = new HashSet<Toy>();public Long getChildId() {return childId;}public void setChildId(Long childId) {this.childId = childId;}public String getChildName() {return childName;}public void setChildName(String childName) {this.childName = childName;}public Set<Toy> getToyList() {return toyList;}public void addToy(Toy toy) {toyList.add(toy);}}
package com.fetchsample.example.domain;import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;/*** Hols data related to the toys a child possess* * @author dinuka.arseculeratne* */
@Entity
@Table(name = 'TOYS')
public class Toy {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = 'TOY_ID')/*** The primary key of the TOYS table*/private Long toyId;@Column(name = 'TOY_NAME')/*** The name of the toy*/private String toyName;public Long getToyId() {return toyId;}public void setToyId(Long toyId) {this.toyId = toyId;}public String getToyName() {return toyName;}public void setToyName(String toyName) {this.toyName = toyName;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((toyName == null) ? 0 : toyName.hashCode());return result;}@Override/*** Overriden because within the child class we use a Set to* hold all unique toys*/public boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Toy other = (Toy) obj;if (toyName == null) {if (other.toyName != null)return false;} else if (!toyName.equals(other.toyName))return false;return true;}@Overridepublic String toString() {return 'Toy [toyId=' + toyId + ', toyName=' + toyName + ']';}}

如您所見,我們有兩個簡單的實體分別代表孩子和玩具。 這個孩子與這些玩具有一對多的關系,這意味著一個孩子可以擁有許多玩具(哦,我多么想念我的童年時代)。 之后,我們需要與數據進行交互,因此讓我們繼續定義DAO(數據訪問對象)接口和實現。

package com.fetchsample.example.dao;import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import com.fetchsample.example.domain.Child;/*** The basic contract for dealing with the {@link Child} entity* * @author dinuka.arseculeratne* */
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public interface ChildDAO {/*** This method will create a new instance of a child in the child table* * @param child*            the entity to be persisted*/public void persistChild(Child child);/*** Retrieves a child without his/her toys* * @param childId*            the primary key of the child table* @return the child with the ID passed in if found*/public Child getChildByIdWithoutToys(Long childId);/*** Retrieves the child with his/her toys* * @param childId*            the primary key of the child table* @return the child with the ID passed in if found*/public Child getChildByIdWithToys(Long childId);/*** Retrieves the child by the name and with his/her toys* * @param childName*            the name of the child* @return the child entity that matches the name passed in*/public Child getChildByNameWithToys(String childName);}
package com.fetchsample.example.dao.hibernate;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import com.fetchsample.example.dao.ChildDAO;
import com.fetchsample.example.domain.Child;/*** The hibernate implementation of our {@link ChildDAO} interface* * @author dinuka.arseculeratne* */
public class ChildDAOHibernateImpl extends HibernateDaoSupport implementsChildDAO {/*** {@inheritDoc}*/public void persistChild(Child child) {getHibernateTemplate().persist(child);}/*** {@inheritDoc}*/public Child getChildByIdWithoutToys(Long childId) {return getHibernateTemplate().get(Child.class, childId);}/*** {@inheritDoc}*/public Child getChildByIdWithToys(Long childId) {Child child = getChildByIdWithoutToys(childId);/*** Since by default the toys are not loaded, we call the hibernate* template's initialize method to populate the toys list of that* respective child.*/getHibernateTemplate().initialize(child.getToyList());return child;}/*** {@inheritDoc}*/public Child getChildByNameWithToys(String childName) {return (Child) getHibernateTemplate().findByNamedQueryAndNamedParam(Child.Constants.FIND_CHILD_BY_NAME_QUERY,Child.Constants.CHILD_NAME_PARAM, childName).get(0);}}

一個簡單的合同。 我有四種主要方法。 當然,第一個只是將子實體持久化到數據庫中。

第二種方法通過傳入的主鍵來檢索Child,但不提取玩具。

第三種方法首先獲取Child,然后使用Hibernate模板的initialize()方法檢索Child的玩具。 請注意,當您調用initialize()方法時,hibernate將把您LAZY定義的集合獲取到您檢索的Child代理中。

最終方法還可以檢索“兒童”的玩具,但這一次使用命名查詢。 如果返回到Child實體的Named查詢,則可以看到我們使用了“ left join fetch ”。 當返回有資格的Child實體時,實際上是關鍵字fetch也會初始化玩具集合。 最后,我有我的主班來測試我們的功能;

package com.fetchsample.example;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.fetchsample.example.dao.ChildDAO;
import com.fetchsample.example.domain.Child;
import com.fetchsample.example.domain.Toy;/*** A test class* * @author dinuka.arseculeratne* */
public class ChildTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext('com/fetchsample/example/spring-context.xml');/*** First we initialize a child*/Child child = new Child();/*** A cool ben 10 action figure*/Toy ben10 = new Toy();ben10.setToyName('Ben 10 figure');/*** A even more cooler spider man action figure*/Toy spiderMan = new Toy();spiderMan.setToyName('Spider man figure');child.setChildName('John');/*** Add the toys to the collection*/child.addToy(ben10);child.addToy(spiderMan);ChildDAO childDAO = (ChildDAO) context.getBean('childDAO');childDAO.persistChild(child);Child childWithoutToys = childDAO.getChildByIdWithoutToys(1L);// The following line will throw a lazy initialization error since we have// defined fetch type as LAZY in the Child domain class.// System.out.println(childWithToys.getToyList().size());Child childWithToys = childDAO.getChildByIdWithToys(1L);System.out.println(childWithToys.getToyList().size());Child childByNameWithToys = childDAO.getChildByNameWithToys('John');System.out.println(childByNameWithToys.getToyList().size());}
}

將基礎實體定義為LAZY是一種好習慣,因為在很多情況下,您可能不希望實體內的集合,而只想與基礎實體中的數據進行交互。 但是,如果需要集合的數據,則可以使用前面提到的任何一種方法。

今天就是這樣。 對于任何想嘗試該示例的人,我都在這里上傳了該示例。

參考: “ 我的旅程” IT博客中的JCG合作伙伴 Dinuka Arseculeratne 舉例說明了使用休眠模式進行延遲/延遲加載 。


翻譯自: https://www.javacodegeeks.com/2012/08/hibernate-lazyeager-loading-example.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371439.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371439.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371439.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

讀者使用計算機終端是指,全國2010年10月自學考試管理系統中計算機應用真題及答案...

A.上級模塊向下級模塊傳遞控制信號B.下級模塊對上級模塊傳遞控制信號C.同級模塊之間傳遞數據或控制信號D.上級模塊向下級模塊傳遞數據信號18.“客戶”數據表結構為&#xff1a;客戶編號、手機號、購物金額&#xff0c;合理的字段類型為( )A.字符型&#xff0c;字符型&#xff0…

軟件測試HW02-------fault error failure

程序一 問題一&#xff1a;i應該>0&#xff1b; 問題二&#xff1a; x為空 問題三&#xff1a;test x[2, 3, 5]; y 3;問題四:test: x[2]; y 3&#xff1b;程序二問題一&#xff1a;循環應該反過來;問題二&#xff1a;無;問題三&#xff1a;test:x[1];問題四:test: x[1,2,3…

Mathematica圖片局部變色

這篇博客來源于Stack-Exchange上的一個帖子&#xff0c;問題描述如下&#xff1a;如何將圖中的紅球變為藍球&#xff1f; 這個問題下面有很多答案&#xff0c;我選了最好的一個答案&#xff0c;代碼如下 img Import["C:/Users/1/Desktop/red.jpg"]; getReds[x_Image…

在WebLogic 12c上運行RichFaces

我最初以為我可以在幾個月前寫這篇文章。 但是我最終被不一樣的事情所淹沒。 其中之一是&#xff0c;它無法像我在4.0版本中那樣簡單地啟動RichFaces展示柜。 有了所有的JMS magic和不同的提供者檢查&#xff0c;這已經成為簡單構建和部署它的挑戰。 無論如何&#xff0c;我愿意…

Spring Boot系列教程一:Eclipse安裝spring-tool-suite插件

一.前言 一直使用eclipse&#xff0c;個人習慣選用Eclipsespring-tool-suite進行開發&#xff0c;特別注意Eclipse要選用對應的spring-tool-suite進行安裝&#xff0c;這點筆者浪費了好長時間&#xff0c;以下為對應的版本。eclipse-kepler.4.3.1–>springsource-tool-suite…

湖南工程學院計算機網絡考試,湖南工程學院 計算機網絡期末試卷試題

湖南工程學院 計算機網絡期末試卷試題湖南工程學院 計算機網絡 期末試題(計算機10級&#xff0c;90%的題目)1 從邏輯功能上看,計算機網絡可分為哪兩個子網?答&#xff1a;通信子網和資源子網 2 數據鏈路層的最基本功能答&#xff1a;數據鏈路層的最基本的功能是向該層用戶提供…

C#設計模式(11)——外觀模式(Facade Pattern)

一、引言 在軟件開發過程中&#xff0c;客戶端程序經常會與復雜系統的內部子系統進行耦合&#xff0c;從而導致客戶端程序隨著子系統的變化而變化&#xff0c;然而為了將復雜系統的內部子系統與客戶端之間的依賴解耦&#xff0c;從而就有了外觀模式&#xff0c;也稱作 ”門面“…

OS X Mountain Lion上的多個Java版本

在Mountain Lion之前&#xff0c;Java被捆綁在OS X中。似乎在升級期間&#xff0c;我在計算機上安裝的Java 6版本被刪除了。 顯然&#xff0c;在升級過程中卸載Java的原因是Java運行時存在的安全問題。通過這種方式&#xff0c;您不得不安裝可解決此安全問題的最新版本。 所以我…

Oracle鎖機制的總結【轉】

最近在研究Oracle鎖機制的時候發現網上的資料魚龍混雜將&#xff0c;很多將問題復雜化&#xff0c;讓人感覺沒有條理性。經過查詢原始理論資料&#xff0c;總結如下&#xff1a; 在數據庫理論中&#xff0c;我們知道。我們在執行并發訪問數據庫表時&#xff0c;如果沒有任何一致…

2020暨陽學院園林計算機考研考場,【圖片】2020考研,老學長教你如何規劃!【計算機考研吧】_百度貼吧...

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓二、關鍵一步——院校選擇我把各位同學的院校選擇階段分為以上幾個階段&#xff0c;因為考研這一年中&#xff0c;很多人的目標院校并不是固定不變的&#xff0c;而是隨著不同階段而改變的。學長我在大三下學期這一時間段內也多次更…

List Box 控件

1 //定義變量&#xff0c;并關聯控件與變量。IDC_RecvData為控件ID&#xff0c;recvData為控件對應的變量名 2 CListBox recvData; 3 4 DDX_Control(pDX, IDC_RecvData, recvData); 5 6 //向List Box控件IDC_RecvData中添加一行數據 7 CString str&#xff1b; 8 recvData.Ad…

JavaOne 2012:向上,向上和向外:使用Akka擴展軟件

在最后的社區主題演講后&#xff0c;我前往希爾頓金門大橋3/4/5觀看了維克多巴生 &#xff08; Viktor Klang &#xff09;的&#xff08; Typesafe &#xff09;“上&#xff0c;下&#xff0c;外&#xff1a;Akka”演講。 巴生&#xff08;Klang&#xff09;是Akka的技術主管…

華北科技學院計算機期末考試,華北科技學院 專業計算機 考試專用

1不能應用修剪命令“trim”進行修剪的對象是(D、文字) 。2. 命令行(B.不能隨意移動)3. 布爾運算中差集的熱鍵為(A.SU)4. 定距等分點用( C.DIST)命令5. 標高是以( B.厘米) 為單位6. 在建筑平面圖中用以指明朝向的是( B.指北針)7. A3圖紙的尺寸是( c.420x297)8. 既可以繪制直線&a…

redux-plain-english-workflow

https://quickleft.com/blog/redux-plain-english-workflow/轉載于:https://www.cnblogs.com/skating/p/6495384.html

Spring測試支持和上下文緩存

Spring為單元測試和集成測試提供了全面的支持-通過注釋來加載Spring應用程序上下文&#xff0c;并與JUnit和TestNG等單元測試框架集成。 由于為每個測試加載大型應用程序上下文需要時間&#xff0c;因此Spring智能地為測試套件緩存應用程序上下文–通常&#xff0c;當我們通過a…

perl6正則 4: before / after 代碼斷言: ?{} / !{}

<?before> <? befor XXX> 某字符在 xxx 之前 <?after > <?after XXX> 某字符之后有XXX 對應的取反分別為: <!before > <!before XXX> XXX之前沒有 <!after> <!after xxx> 某字符后面不是 xxx say "foobar" ~~…

mac 下JDK 與 tomcat 的安裝與配置

一.Mac下JDK的安裝 1.先檢測Mac是否已經安裝過JDK&#xff0c;在終端中輸入java 或者 javac 顯示說明&#xff0c;表明已經安裝過JDK&#xff0c;JDK版本查詢終端鍵入java &#xff0d;version&#xff0c;終端會返回JDK的版本號。 2.如果沒有安裝JDK&#xff0c;登陸 http://w…

新型發明創造大賽計算機類,2017年發明杯全國高職高專大學生創新創業大賽

以“發明創新實現夢想、創意創業改變生活”主題活動為依托&#xff0c;把課內與課外教育相結合&#xff0c;學校教育、家庭教育與社會教育相結合&#xff0c;培養廣大在校大學生的科技創新意識和實踐動手能力&#xff0c;激發他們設計創造的樂趣&#xff0c;使廣大大學生大膽創…

如何寫出安全的API接口(參數加密+超時處理+私鑰驗證+Https)- 續(附demo)

轉載&#xff1a;http://www.cnblogs.com/codeon/p/6123863.html 上篇文章說到接口安全的設計思路&#xff0c;如果沒有看到上篇博客&#xff0c;建議看完再來看這個。 通過園友們的討論&#xff0c;以及我自己查了些資料&#xff0c;然后對接口安全做一個相對完善的總結&#…

PrimeFaces在GlassFish 3.1.2.2上推動大氣

PrimeFaces 3.4在三天前問世。 除了通常令人敬畏的新組件和更新組件之外&#xff0c;它還包括新的PrimeFaces Push框架。 基于Atmosphere&#xff0c;這為您的應用程序提供了簡單的推送機制。 這是在最新的GlassFish 3.1.2.2上配置和運行它的方法。 準備工作 像往常一樣&#…