休眠提示:排序和排序

讓我們介紹另一個休眠性能提示。 你還記得以前的休眠的模式后 ? 我們有一個與一對多協會有關的星際飛船和軍官。

@Entity
public class Starship {@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private Long id;public Long getId() {return id;}protected void setId(Long id) {this.id = id;}@OneToMany(mappedBy="starship", cascade={CascadeType.ALL}) private List<Officer> officers = new ArrayList<Officer>();public List<Officer> getOfficers() {return Collections.unmodifiableList(officers);}protected void setOfficers(List<Officer> officers) {this.officers = officers;}public void addOfficer(Officer officer) {officer.setStarship(this);this.officers.add(officer);}//more code
}@Entity
public class Officer {@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private Long id;public Long getId() {return id;}protected void setId(Long id) {this.id = id;}@ManyToOne private Starship starship; public Starship getStarship() {return starship;}protected void setStarship(Starship starship) {this.starship = starship;}//more code
}

現在我們有下一個要求:
我們將按字母順序將所有軍官分配給星際飛船。
為了解決這個要求,我們可以:

  1. 使用order by子句實現HQL查詢。
  2. 使用排序方法。
  3. 使用訂單方法。

第一個解決方案在性能方面不錯,但是作為開發人員意味著更多的工作,因為我們應該編寫一個查詢來查找按名稱排序的給定飛船的所有人員,然后在DAO層中創建finder方法(如果您使用的是DAO模式 ) 。
讓我們探索第二個解決方案,我們可以使用SortedSet類作為關聯,并使Officer實現Comparable ,因此Officer具有 自然秩序。 該解決方案的工作量少于第一個,但需要在關聯定義上使用@Sort 休眠注釋,因此讓我們修改以前的模型以滿足我們的新要求。請注意, JPA規范中沒有等效的注釋。 首先我們要實施

@Entity
public class Officer implements Comparable<Officer>{//getters, setters, equals, ... codepublic int compareTo(Officer officer) {return this.name.compareTo(officer.getName());}}

官員類中的可比接口。

我們通過簡單地比較名稱字段來按名稱訂購人員。 下一步是使用@Sort注釋關聯。

@Entity
public class Starship {//more code@OneToMany(mappedBy="starship", cascade={CascadeType.ALL})@Sort(type=SortType.NATURAL)private SortedSet>Officer< officers = new TreeSet>Officer<();public SortedSet>Officer< getOfficers() {return Collections.unmodifiableSortedSet(officers);}protected void setOfficers(SortedSet>Officer< officers) {this.officers = officers;}public void addOfficer(Officer officer) {officer.setStarship(this);this.officers.add(officer);}
}

注意,現在使用SortedSet而不是List來實現人員關聯。 此外,我們在關系中添加了@Sort批注,表明官員應自然而有序。 在完成本文之前,我們將在@Sort主題中堅持使用更多內容,但到目前為止已經足夠。

最后是一種方法,該方法可以按名稱對給定星際飛船的所有人員進行排序,并將其打印在日志文件中。

EntityManager entityManager = this.entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();transaction.begin();
log.info("Before Find Starship By Id");Starship newStarship = entityManager.find(Starship.class, starshipId);
SortedSet<Officer> officers = newStarship.getOfficers();for (Officer officer : officers) {log.info("Officer name {} with rank {}", officer.getName(), officer.getRank());
}log.info("After Find Starship By Id and Before Commit");transaction.commit();
entityManager.close();

所有人員均按其姓名排序,但讓我們檢查將哪些查詢發送到RDBMS

Hibernate: select starship0_.id as id1_0_, starship0_.affiliationEnum as affiliat2_1_0_, starship0_.launched as launched1_0_, starship0_.height as height1_0_, starship0_.length as length1_0_, starship0_.power as power1_0_, starship0_.width as width1_0_, starship0_.registry as registry1_0_, starship0_.starshipClassEnum as starship9_1_0_ 
from Starship starship0_ where starship0_.id=?Hibernate: select officers0_.starship_id as starship7_1_1_, officers0_.id as id1_, officers0_.id as id0_0_, officers0_.affiliationEnum as affiliat2_0_0_, officers0_.homePlanet as homePlanet0_0_, officers0_.name as name0_0_, officers0_.rank as rank0_0_, officers0_.speciesEnum as speciesE6_0_0_, officers0_.starship_id as starship7_0_0_ 
from Officer officers0_ where officers0_.starship_id=?

第一個查詢是在EntityManager實例查找星艦上調用find方法導致的。

因為默認情況下,當我們調用getOfficers方法并且第一次訪問SortedSet時 ,一對多關系是惰性的,所以執行第二個查詢來檢索所有人員。 看到查詢中不存在order by子句,但仔細查看輸出,會按字母順序檢索人員。

<Officer name Beverly Crusher with rank COMMANDER>
<Officer name Data with rank LIEUTENANT_COMMANDER>
<Officer name Deanna Troi with rank COMMANDER>
<Officer name Geordi La Forge with rank LIEUTENANT>
<Officer name Jean-Luc Picard with rank CAPTAIN>
<Officer name William Riker with rank COMMANDER>
<Officer name Worf with rank LIEUTENANT>

那么誰是整理人員實體? 說明在@Sort注釋上。 在休眠狀態下,一個排序的集合在Java內存中排序,它負責使用compareTo方法對數據進行排序。
顯然,此方法不是對元素集合進行排序的最佳性能方法。 在使用SQL子句和使用注釋而不是編寫查詢之間,我們可能需要一種混合解決方案。

這使我們使用排序方法來解釋第三種可能性。 @OrderBy注釋(可以用作休眠注釋和JPA注釋),讓我們指定如何通過在生成的SQL中添加“ order by ”子句來對集合進行排序

請記住,使用javax.persistence.OrderBy允許我們通過對象屬性指定集合的??順序,同時org.hibernate.annotations.OrderBy對集合進行排序,將SQL的片段(不是HQL )直接附加到order by子句中。
現在不應該觸動Officer類,我們不需要實現compareTo方法或java.util.Comparator 。 我們只需要使用@OrderBy注釋來注釋人員字段。 由于在這種情況下,我們通過簡單的屬性進行排序,因此使用JPA注釋來保持與其他“支持JPA的ORM引擎的完全兼容性。 默認情況下,假定升序。

@Entity
public class Starship {//code@OneToMany(mappedBy="starship", cascade={CascadeType.ALL})@OrderBy("name")private List<Officer> officers = new ArrayList<Officer>();public List<Officer> getOfficers() {return Collections.unmodifiableList(officers);}protected void setOfficers(List<Officer> officers) {this.officers = officers;}public void addOfficer(Officer officer) {officer.setStarship(this);this.officers.add(officer);}
}

如果我們重新運行所有人員的方法,則會發送下一個查詢:

Hibernate: select starship0_.id as id1_0_, starship0_.affiliationEnum as affiliat2_1_0_, starship0_.launched as launched1_0_, starship0_.height as height1_0_, starship0_.length as length1_0_, starship0_.power as power1_0_, starship0_.width as width1_0_, starship0_.registry as registry1_0_, starship0_.starshipClassEnum as starship9_1_0_ 
from Starship starship0_ where starship0_.id=?Hibernate: select officers0_.starship_id as starship7_1_1_, officers0_.id as id1_, officers0_.id as id0_0_, officers0_.affiliationEnum as affiliat2_0_0_, officers0_.homePlanet as homePlanet0_0_, officers0_.name as name0_0_, officers0_.rank as rank0_0_, officers0_.speciesEnum as speciesE6_0_0_, officers0_.starship_id as starship7_0_0_ 
from Officer officers0_ where officers0_.starship_id=? order by officers0_.name asc

這兩個查詢仍然執行,但請注意,現在select查詢也包含order by子句。

使用此解決方案,您可以節省處理時間,從而允許RDBMS快速對數據進行排序,而不是一旦接收到Java中的數據就對其進行排序。
此外, OrderBy批注不會強制您使用SortedSetSortedMap集合。 您可以使用HashMapHashSet甚至Bag之類的任何集合,因為hibernate將在內部分別使用LinkedHashMapLinkedHashSetArrayList

在這個例子中,我們已經看到了正確選擇訂購策略的重要性。 只要有可能,您都應該嘗試利用RDBMS的功能,因此您的第一個選擇應該是使用OrderBy注釋( 休眠JPA ),而不是Sort 。 但是有時OrderBy子句是不夠的。 在這種情況下,我建議您使用具有自定義類型的Sort注釋(使用java.util.Comparator類),而不是按自然順序進行中繼以避免觸摸模型類。

@Sort(type=SortType.COMPARATOR, comparator=TimeComparator.class)

我希望這篇文章可以幫助您了解休眠狀態下 “排序”“順序”之間的區別。

保持學習。

參考: Hibernate提示:我們的JCG合作伙伴 Alex Soto的“ 排序和排序”在One Jar To Rule All All博客中。


翻譯自: https://www.javacodegeeks.com/2012/04/hibernate-tip-sort-and-order.html

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

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

相關文章

java 基本類型 線程安全_java的基本類型和i++線程安全性的深入解析

在java中&#xff0c;除了long和double的8個字節、64位比特的變量外&#xff0c;其他的基本變量都是原子性的。java存儲模型要求獲取和存儲操作都為原子性&#xff0c;但是對于非volatile的long和double變量&#xff0c;jvm允許將64位的讀或寫劃分為兩個32位的操作。如果讀和寫…

MySQL配置文件mysql.ini參數詳解

my.ini&#xff08;Linux系統下是my.cnf&#xff09;&#xff0c;當mysql服務器啟動時它會讀取這個文件&#xff0c;設置相關的運行環境參數。 my.ini分為兩塊&#xff1a;Client Section和Server Section。 Client Section用來配置MySQL客戶端參數。 要查看配置參數可以用下面…

微信公眾平臺和微信開放平臺的區別

自己也剛開始做微信開發&#xff0c;先寫寫自己的認識&#xff1a; 用微信公眾平臺可以做手機端H5頁面的微信登錄&#xff0c;微信支付 用微信開放平臺可以做PC端網頁的微信登錄。 轉載于:https://www.cnblogs.com/mafeng/p/5610770.html

java 傳遞bean_如何將bean作為參數傳遞給JSP標記?

我ve created a custom JSP tag that is supposed to accept a list of products to render, but I我無法弄清楚如何將列表傳遞給標簽 . 產品列表作為頁面范圍的bean存在 . Web應用程序使用Struts taglib在Struts 1.2.x中編寫 .這是我的代碼的簡化版本&#xff1a;renderProduc…

Business Component(BC)和Business Object(BO)

Siebel應用架構的一個成功的地方就是在應用里引入了BC&#xff0c;BO的概念&#xff0c;從而使得幾千張關系數據表能夠按照業務的含義組織成業務對象&#xff0c;對于業務人員而言具有了業務上的含義&#xff0c;而不僅僅是從技術人員的觀點來對待數據&#xff08;就是關系表而…

NetBeans可用性提示

的Java IDE都來了&#xff0c;因為在很長的路要走天的JBuilder的 &#xff08;盡管JBuilder中似乎是一個值得歡迎提前在時間&#xff09;。 當今的Java IDE&#xff08;例如NetBeans &#xff0c; Eclipse &#xff0c; IntelliJ IDEA和JDeveloper &#xff09;是非常先進的工具…

一個JVM進程啟動后里面有幾個線程

在寫Java程序時&#xff0c;通常我們管只有一個main函數&#xff08;而沒有別的Thread或Runnable的程序&#xff09;叫單線程程序。但是我們寫的這個所謂的單線程程序只是JVM這個程序中的一個線程&#xff0c;JVM本身是一個多線程的程序&#xff0c;至少得有一個垃圾收集器線程…

WPF 反編譯后錯誤處理

1. 首先&#xff0c;手動創建一個WPF工程&#xff08;WpfApplicationReflectorDemo&#xff09; 2. 把生成的WpfApplicationReflectorDemo.exe 拖到ILSpy里 3.點擊 File -> Save Code...: 相應的代碼會生成到指定地方。 4. 打開應用程序&#xff0c;并且編譯它&#xff0c;此…

JavaFX 2 GameTutorial第1部分

介紹 我相信大多數軟件開發人員可能會在年輕人&#xff08;年輕人&#xff09;一生中的某一時刻被迫創建游戲來幫助他們學習編程語言&#xff08;我知道我確實做到了&#xff09;。 以前&#xff0c;我的第一臺計算機實際上是Franklin Ace 1000 &#xff0c;后來是Apple [] 。 …

虛擬現實-VR-UE4-認識UE4

VR的火熱&#xff0c;讓每個人都想參與一下&#xff0c; 公司在展會上面搞了一個VR的Demo&#xff0c;關注度超出預期&#xff0c;使得公司高層決定來個VR項目 所以 關于UE4 百度百科地址&#xff1a;http://baike.baidu.com/link?urlmEmbwOcqEuqtkfdu9lNdxVtWAkv0Q6UHZ4VgIHr…

java concurrent 例子_[Java Concurrent] 并發訪問共享資源的簡單案例

EvenGenerator 是一個偶數生成器&#xff0c;每調用一個 next() 就會加 2 并返回疊加后結果。在本案例中&#xff0c;充當被共享的資源。EvenChecker 實現了 Runnable 接口&#xff0c;可以啟動新的線程執行 run() 任務&#xff0c;用于檢測所指向的偶數生成器是否每次都返回偶…

OSGI實戰第一章

第一章 解開OSGI的面紗 OSGI是什么&#xff1f;是Java平臺的一個模塊化層。模塊化&#xff1a;軟件應用程序的代碼被分割為表示獨立內容的邏輯單元&#xff0c;可簡化開發&#xff0c;可通過強化邏輯模塊的界限來提高可維護性。Java模塊化的不足a) Java使用訪問…

輕松完成Birt報告

這是使用Birt插件在Eclipse中構建報告的完整指南。 Birt或Business Intelligence and Reporting工具是一種無需編寫太多Java代碼即可生成報告的工具。 如果您使用的是ireport&#xff0c;那么您知道我在說什么&#xff1a;&#xff09;&#xff08;晶體報告..毫無意義&#xff…

MySQL 的 RowNum 實現

MySQL 下面沒有RowNum&#xff0c;排序后序號卻無法得到&#xff0c;比較麻煩&#xff01; SELECT rownum:rownum1 rownum, CollectSn From(SELECT rownum:0,bbgmain.* FROM qbdb.bbgmain WHERE collectsn! ORDER BY collectsn limit 10) t轉載于:https://www.cnblogs.com/hym-…

java jdbc事務管理_hibernate事務管理 (jdbc jta)

評論# re: hibernate事務管理 (jdbc jta)2007-07-29 10:18pigJTA事務的開始Transaction tx session.beginTransaction();應該不是這樣吧&#xff0c;應該是從容器中獲得。 回復 更多評論# re: hibernate事務管理 (jdbc jta)2007-07-29 12:35slxpig建議看看hibernate referen…

@Resource VS @Autowired

Resource 和 Autowired 均是用于bean注入的注解&#xff0c;都可以寫在字段和setter方法上,如果都寫在字段上&#xff0c;就無需寫setter方法。 Autowired 由Spring的org.springframework.beans.factory.annotation.Autowired提供 默認byType方式注入&#xff0c;并且對象不能為…

用于Spring應用程序的Gradle原型

我發布了Gradle原型&#xff0c;可用于基于Springframework創建Java / Groovy應用程序。 當然&#xff0c;它不是一個真正的原型&#xff0c;因為這樣的創作是不可能的 。不過&#xff0c;你可以創建&#xff0c;編輯和部署應用服務器很少的步驟。 對于可部署的軟件項目而言&am…

java tm無響應_Java(TM) Platform SE binary 未響應 是怎么個情況?

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓988098 [Thread-10] INFO sound.oo0O - Creating streaming player for music with id [faction_pirate_encounter_02_hostile.ogg]988099 [Thread-10] INFO sound.OooO - Playing music with id [faction_pirate_encounter_02_hos…

ROS and PCL install

ROS hydro安裝指南&#xff1a; http://wiki.ros.org/cn/hydro/Installation/Ubuntu &#xff08;加ppa源后直接安裝&#xff09; Linux OpenCV安裝指南&#xff1a;http://blog.sciencenet.cn/blog-571755-694742.html &#xff08;從源代碼編譯&#xff09; PCL&#xff1a;…

揭開Python科學計算的面紗

春牛春杖。無限春風來海上。便與春工。染得桃紅似肉紅。 春幡春勝。一陣春風吹酒醒。不似天涯。卷起楊花似雪花。 標準的Python中用列表保存一組值&#xff0c;可以當做數組使用&#xff0c;但是由于其值類型任意&#xff0c;所以列表中保存的是指針&#xff0c;這樣的話保存一…