Java程式員從笨鳥到菜鳥之(六十一)細談Hibernate(十二)hibernate查詢排序組件映射

來源:互聯網
上載者:User

            

            在實際開發過程中,有很多使用者需要時要把查詢出來的結果進行排序顯示,而不是在資料庫裡面那樣順序混亂那樣的顯示,這樣的話我們不得不要對資料進行排序了,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如何使用order by 查詢子句以返回排序後的結果集。下面我們就以一個具體的執行個體來具體看一下資料庫排序的內容

我們就以學生和團隊的關係來說一下:首先來看一下實體之間的資料結構關係:

Student.java

public class Student {  private String id;  private String name;  private String description;  private Team team;.************set、get方法省略}

Team.java

public class Team {   private String id;   private String teamname;   private Set students;***********set、get方法省略}

      從實體上我們可以看出,學生和團隊是一個多對一得資料關係,這個我們以前都看過,也寫過,相信大家都有已經很熟悉了。所以在此具體的設定檔我們也不多寫了,我們主要來看一下配置排序的地方,下面我們看一下配置的詳細代碼:

<!-- 以名稱降序返回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屬性即可。

下面我們就具體來看一下測試代碼:

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();

運行這塊代碼,我們一起來看一下控制台的列印結果:

測試結果:

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 deschellodefaultbug

     從上面輸出的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()方法的原始碼如下:

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是沒有標識的,它是一個邏輯組成部分,完全從屬於某個實體,這樣就在傳統資料庫上,實現了對象的細粒度劃分,層次分明,實現了物件導向的領域劃分

見:

                      

把User和Employee中共同的屬性(各種連絡方式)拿出來,放在(抽象到)到一個單獨的類中。這樣物理上看有三個類,不過實體類還是只有User和Employee兩個,也就是說資料庫裡只有User和Employee兩張表。

下面我們就來看一下user和contact的實體及相關配置:

user.java

public class User {private int id;private String name;//連絡方式private Contact contact;********************set、get省略}

contact.java

public class Contact {private String address;private String contactTel;private String email;private String zipCode;********************set、get省略}

user.hbm.xml

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><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="address"/><property name="contactTel"/><property name="email"/><property name="zipCode"/></component></class></hibernate-mapping>

        從配置上來看,其實這個地方很好理解,user把contact看做是組成的一部分,只是把他抽出一個單獨的實體類了而已,這也正好體現了代碼的複用性,其實他就是一對一關聯性的映射。

       如果想要產生兩張表,hibernate也提供了相關的配置機制,其實只是換了換標籤而已,把component標籤換成composite-element,僅此而已,這樣就能產生兩張表了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.