在實際開發過程中,有很多使用者需要時要把查詢出來的結果進行排序顯示,而不是在資料庫裡面那樣順序混亂那樣的顯示,這樣的話我們不得不要對資料進行排序了,hibernate對資料排序提供了很好的支援,hibernate提供了兩種對查詢到得資料結果進行排序:1:資料庫排序,也就是說在資料庫内部就進行完了排序。2.記憶體排序,也就是說在資料庫中把資料加載到記憶體中在進行排序。其實一般我們推薦使用第二種排序方式,因為在資料庫中排序的性能要遠遠高于在記憶體中排序的性能。
一:資料庫排序
資料庫排序主要是使用集合标簽中的order-by屬性,格式主要是為: order-by="字段名 排序方式”;例如:order-by="name asc”name是指資料庫字段 asc是升序,在hibernate中,<set>、<idbag>、<map>、<list>元素都有order-by屬性,如果設定了該屬性,Hibernate會利用 order by 子句進行排序,使用order-by屬性,我們可以通過hbm檔案執行生成的SQL如何使用orderby 查詢子句以傳回排序後的結果集。下面我們就以一個具體的執行個體來具體看一下資料庫排序的内容
我們就以學生和團隊的關系來說一下:首先來看一下實體之間的資料結構關系:
Student.java
[java] view plain copy print ?
- public class Student {
- private String id;
- private String name;
- private String description;
- private Team team;
- .************set、get方法省略
- }
Team.java
[java] view plain copy print ?
- public class Team {
- private String id;
- private String teamname;
- private Set students;
- ***********set、get方法省略
- }
從實體上我們可以看出,學生和團隊是一個多對一得資料關系,這個我們以前都看過,也寫過,相信大家都有已經很熟悉了。是以在此具體的配置檔案我們也不多寫了,我們主要來看一下配置排序的地方,下面我們看一下配置的詳細代碼:
[html] view plain copy print ?
- <!-- 以名稱降序傳回student集合 -->
- <set name="students" table="studentOrder" cascade="all" order-by="name desc">
- <key column="team_id"></key>
- <one-to-many class="Collection.Order.Student"/>
- </set>
從上面可以看出,其實配置資料庫排序很簡單,僅僅是在集合标簽上配置一個order-by屬性即可。
下面我們就具體來看一下測試代碼:
[java] view plain copy print ?
- Transaction t=session.beginTransaction();
- Team team=(Team)session.createQuery("from Team t where t.teamname='team1'").uniqueResult();
- Set result=team.getStudents();
- for (Iterator iterator = result.iterator(); iterator.hasNext();) {
- Student object = (Student) iterator.next();
- System.out.println(object.getName());
- }
- t.commit();
運作這塊代碼,我們一起來看一下控制台的列印結果:
測試結果:
[html]
view plain
copy
print
?
- Hibernate: select team0_.id as id1_, team0_.teamname as teamname1_ from teamOrder team0_ where team0_.teamname='team1'
- Hibernate: select students0_.team_id as team4_1_, students0_.id as id1_, students0_.id as id0_0_, students0_.name as name0_0_, students0_.description as descript3_0_0_, students0_.team_id as team4_0_0_ from studentOrder students0_ where students0_.team_id=? order by students0_.name desc
- hello
- default
- bug<span style="font-size:18px;color:red;"></span>
從上面輸出的sql語句就可以看出,我們查詢到得資料時以student表中的name進行排序的。是以我們資料庫排序的配置就這麼結束了。
二.記憶體排序
記憶體排序,顧名思義,就是在記憶體中排序,把查詢到得結果加載到記憶體以後驚醒排序。Hibernate在配置檔案中也給我提供了記憶體排序的配置,那就是sort屬性,它有兩個屬性值可以直接使用,分别是unsorted(不排序)以及natural(自然排序,即升序),此外,我們還可以自定義排序規則,方式是定義一個類,讓其實作Comparator接口,并且實作該接口中的compare方法,在該方法中實作排序規則即可。然後将該自定義排序規則的類名作為sort的屬性值即可。<set>和<map>元素都具有sort屬性,如果設定了該屬性,就會對記憶體中的集合對象進行排序。
<set>元素的sort屬性為natural,表示對集合中的字元串進行自然排序。Hibernate采用org.hibernate.PersistentSortedSet作為Set的實作類,PersistentSortedSet類實作了 java.util.SortedSet接口。當Session儲存一個對象時,會調用 org.hibernate.type.SortedSetType類的wrap()方法,把對象的集合屬性包裝為 SortedSet類的執行個體,下面我們看一下wrap()方法的源代碼如下:
[java] view plain copy print ?
- public PersistentCollection wrap
- (SessionImplementor session, Object collection) {
- return new PersistentSortedSet
- ( session, (java.util.SortedSet) collection );
- }
從wrap()方法的源代碼看出,應用程式中建立的對象的集合屬性必須是java.util.SortedSet類型,否則以上wrap()方法會抛出ClassCastException。
其實記憶體排序和資料庫排序是一樣的,隻是配置的參數不同而已,都是在集合标簽配置一下,是以在此我們就不以示例示範了。
三、元件映射(component)
在hibernate中,component是某個實體對象的邏輯組成部分,它與實體的根本差別是,component是沒有辨別的,它是一個邏輯組成部分,完全從屬于某個實體,這樣就在傳統資料庫上,實作了對象的細粒度劃分,層次分明,實作了面向對象的領域劃分
見下圖:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZwpmLyIDM58FNxADOwEDOzMTMvw1Ny8CX1AjMxAjMvw1ckF2bsBXdvwFdl5mLuR2cj5Set1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
把User和Employee中共同的屬性(各種聯系方式)拿出來,放在(抽象到)到一個單獨的類中。這樣實體上看有三個類,不過實體類還是隻有User和Employee兩個,也就是說資料庫裡隻有User和Employee兩張表。
下面我們就來看一下user和contact的實體及相關配置:
user.java
[java] view plain copy print ?
- public class User {
- privateint id;
- privateString name;
- //聯系方式
- privateContact contact;
- ********************set、get省略
- }
contact.java
[java] view plain copy print ?
- public class Contact {
- privateString address;
- privateString contactTel;
- privateString email;
- privateString zipCode;
- ********************set、get省略
- }
user.hbm.xml
[html] view plain copy print ?
- <?xmlversionxmlversion="1.0"?>
- <!DOCTYPEhibernate-mapping PUBLIC
- "-//Hibernate/Hibernate MappingDTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <classnameclassname="com.bjsxt.hibernate.User" table="t_user">
- <idnameidname="id">
- <generatorclassgeneratorclass="native"/>
- </id>
- <propertynamepropertyname="name"/>
- <componentnamecomponentname="contact">
- <propertynamepropertyname="address"/>
- <propertynamepropertyname="contactTel"/>
- <propertynamepropertyname="email"/>
- <propertynamepropertyname="zipCode"/>
- </component>
- </class>
- </hibernate-mapping>
從配置上來看,其實這個地方很好了解,user把contact看做是組成的一部分,隻是把他抽出一個單獨的實體類了而已,這也正好展現了代碼的複用性,其實他就是一對一關系的映射。
如果想要生成兩張表,hibernate也提供了相關的配置機制,其實隻是換了換标簽而已,把component标簽換成composite-element,僅此而已,這樣就能生成兩張表了。
在實際開發過程中,有很多使用者需要時要把查詢出來的結果進行排序顯示,而不是在資料庫裡面那樣順序混亂那樣的顯示,這樣的話我們不得不要對資料進行排序了,hibernate 對資料排序提供了很好的支援,hibernate提供了兩種對查詢到得資料結果進行排序:1:資料庫排序,也就是說在資料庫内部就進行完了排序。2.記憶體排序,也就是說在資料庫中把資料加載到記憶體中在進行排序。其實一般我們推薦使用第二種排序方式,因為在資料庫中排序的性能要遠遠高于在記憶體中排序的性能。
一:資料庫排序
資料庫排序主要是使用集合标簽中的order-by屬性,格式主要是為: order-by="字段名 排序方式”;例如:order-by="name asc”name是指資料庫字段 asc是升序,在hibernate中,<set>、<idbag>、<map>、<list>元素都有order-by屬性,如果設定了該屬性,Hibernate會利用 order by 子句進行排序,使用order-by屬性,我們可以通過hbm檔案執行生成的SQL如何使用orderby 查詢子句以傳回排序後的結果集。下面我們就以一個具體的執行個體來具體看一下資料庫排序的内容
我們就以學生和團隊的關系來說一下:首先來看一下實體之間的資料結構關系:
Student.java
[java] view plain copy print ?
- public class Student {
- private String id;
- private String name;
- private String description;
- private Team team;
- .************set、get方法省略
- }
Team.java
[java] view plain copy print ?
- public class Team {
- private String id;
- private String teamname;
- private Set students;
- ***********set、get方法省略
- }
從實體上我們可以看出,學生和團隊是一個多對一得資料關系,這個我們以前都看過,也寫過,相信大家都有已經很熟悉了。是以在此具體的配置檔案我們也不多寫了,我們主要來看一下配置排序的地方,下面我們看一下配置的詳細代碼:
[html] view plain copy print ?
- <!-- 以名稱降序傳回student集合 -->
- <set name="students" table="studentOrder" cascade="all" order-by="name desc">
- <key column="team_id"></key>
- <one-to-many class="Collection.Order.Student"/>
- </set>
從上面可以看出,其實配置資料庫排序很簡單,僅僅是在集合标簽上配置一個order-by屬性即可。
下面我們就具體來看一下測試代碼:
[java] view plain copy print ?
- Transaction t=session.beginTransaction();
- Team team=(Team)session.createQuery("from Team t where t.teamname='team1'").uniqueResult();
- Set result=team.getStudents();
- for (Iterator iterator = result.iterator(); iterator.hasNext();) {
- Student object = (Student) iterator.next();
- System.out.println(object.getName());
- }
- t.commit();
運作這塊代碼,我們一起來看一下控制台的列印結果:
測試結果:
[html]
view plain
copy
print
?
- Hibernate: select team0_.id as id1_, team0_.teamname as teamname1_ from teamOrder team0_ where team0_.teamname='team1'
- Hibernate: select students0_.team_id as team4_1_, students0_.id as id1_, students0_.id as id0_0_, students0_.name as name0_0_, students0_.description as descript3_0_0_, students0_.team_id as team4_0_0_ from studentOrder students0_ where students0_.team_id=? order by students0_.name desc
- hello
- default
- bug<span style="font-size:18px;color:red;"></span>
從上面輸出的sql語句就可以看出,我們查詢到得資料時以student表中的name進行排序的。是以我們資料庫排序的配置就這麼結束了。
二.記憶體排序
記憶體排序,顧名思義,就是在記憶體中排序,把查詢到得結果加載到記憶體以後驚醒排序。Hibernate在配置檔案中也給我提供了記憶體排序的配置,那就是sort屬性,它有兩個屬性值可以直接使用,分别是unsorted(不排序)以及natural(自然排序,即升序),此外,我們還可以自定義排序規則,方式是定義一個類,讓其實作Comparator接口,并且實作該接口中的compare方法,在該方法中實作排序規則即可。然後将該自定義排序規則的類名作為sort的屬性值即可。<set>和<map>元素都具有sort屬性,如果設定了該屬性,就會對記憶體中的集合對象進行排序。
<set>元素的sort屬性為natural,表示對集合中的字元串進行自然排序。Hibernate采用org.hibernate.PersistentSortedSet作為Set的實作類,PersistentSortedSet類實作了 java.util.SortedSet接口。當Session儲存一個對象時,會調用 org.hibernate.type.SortedSetType類的wrap()方法,把對象的集合屬性包裝為 SortedSet類的執行個體,下面我們看一下wrap()方法的源代碼如下:
[java] view plain copy print ?
- public PersistentCollection wrap
- (SessionImplementor session, Object collection) {
- return new PersistentSortedSet
- ( session, (java.util.SortedSet) collection );
- }
從wrap()方法的源代碼看出,應用程式中建立的對象的集合屬性必須是java.util.SortedSet類型,否則以上wrap()方法會抛出ClassCastException。
其實記憶體排序和資料庫排序是一樣的,隻是配置的參數不同而已,都是在集合标簽配置一下,是以在此我們就不以示例示範了。
三、元件映射(component)
在hibernate中,component是某個實體對象的邏輯組成部分,它與實體的根本差別是,component是沒有辨別的,它是一個邏輯組成部分,完全從屬于某個實體,這樣就在傳統資料庫上,實作了對象的細粒度劃分,層次分明,實作了面向對象的領域劃分
見下圖:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZwpmLyIDM58FNxADOwEDOzMTMvw1Ny8CX1AjMxAjMvw1ckF2bsBXdvwFdl5mLuR2cj5Set1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
把User和Employee中共同的屬性(各種聯系方式)拿出來,放在(抽象到)到一個單獨的類中。這樣實體上看有三個類,不過實體類還是隻有User和Employee兩個,也就是說資料庫裡隻有User和Employee兩張表。
下面我們就來看一下user和contact的實體及相關配置:
user.java
[java] view plain copy print ?
- public class User {
- privateint id;
- privateString name;
- //聯系方式
- privateContact contact;
- ********************set、get省略
- }
contact.java
[java] view plain copy print ?
- public class Contact {
- privateString address;
- privateString contactTel;
- privateString email;
- privateString zipCode;
- ********************set、get省略
- }
user.hbm.xml
[html] view plain copy print ?
- <?xmlversionxmlversion="1.0"?>
- <!DOCTYPEhibernate-mapping PUBLIC
- "-//Hibernate/Hibernate MappingDTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <classnameclassname="com.bjsxt.hibernate.User" table="t_user">
- <idnameidname="id">
- <generatorclassgeneratorclass="native"/>
- </id>
- <propertynamepropertyname="name"/>
- <componentnamecomponentname="contact">
- <propertynamepropertyname="address"/>
- <propertynamepropertyname="contactTel"/>
- <propertynamepropertyname="email"/>
- <propertynamepropertyname="zipCode"/>
- </component>
- </class>
- </hibernate-mapping>
從配置上來看,其實這個地方很好了解,user把contact看做是組成的一部分,隻是把他抽出一個單獨的實體類了而已,這也正好展現了代碼的複用性,其實他就是一對一關系的映射。
如果想要生成兩張表,hibernate也提供了相關的配置機制,其實隻是換了換标簽而已,把component标簽換成composite-element,僅此而已,這樣就能生成兩張表了。