1. 程式人生 > >hibernate QBC和QBE精講與案列分析(上)

hibernate QBC和QBE精講與案列分析(上)

轉載:http://blog.sina.com.cn/s/blog_7fff746d0101ese2.html

本章的主要內容包括:

● QBC資料檢索

 

● 連線查詢

● Hibernate的資料檢索策略

  QBC資料檢索

  Hibernate提供了另一種形式的面向物件的查詢方式QBC(Query by Criteria)。這種查詢是以函式API的方式動態地設定查詢條件,組成查詢語句。基本結構是session建立criteria介面,然後呼叫criteria介面的add函式,增加查詢條件(

criterion),然後呼叫criterialist()函式返回查詢結果。

  除了有當前session建立的criteria介面外,Hibernate還提供了在session不可用時,組織查詢語句的遊離態的DetachCriteria類,它的查詢條件設定與criteria類似,只是它不由session建立,而是在需要session可用時,再呼叫getExecutableCriteria()執行查詢。

  另外,為了讓criteria的查詢方法與HQL一樣功能豐富,Hibernate還提供了projections類,用於提供各種函式來產生可以使用聚集函式,進行投影查詢和進行查詢結果設定的各種

projection介面,提供了Restrictions類用於提供各種函式來產生各種criterion作為查詢條件,提供了用於結果排序的order類。

  圖8-1Criteria相關類的結構圖。

 

圖8-1  Criteria相關類圖

  由圖8-1可見,Criteria介面和DetachedCriteria類都繼承了CriteriaSpecification介面,開發人員在使用QBC查詢時,都是直接選擇用CriteriaDetachedCriteria。而它們兩個都是一樣使用可以設定各種查詢條件或者查詢結果的CriterionProjection

等介面。

8.1.1  QBC查詢主要類

  下面分別對QBC查詢中使用的幾個主要介面和類進行介紹。

  1. Criteria介面

  Criteria呼叫add函式新增Criterion物件來組成查詢條件,然後根據查詢條件來查詢持久化類物件。與HQL查詢的Query類一樣,也是由Session呼叫createCriteria()函式建立。

  以下程式碼是檢索價格大於25Product物件。

      Criteria crit = session.createCriteria(Product.class);

          crit.add(Restrictions.gt("price",new Double(25.0)));

          List results = crit.list();

  相應地,HQL實現的程式碼如下:

          Query query = session.createQuery(

                  "from Product where price>:price");

          query.setDouble("price",25.0);

          List results = query.list();

  使用Criteria查詢的步驟是:(ke ruai tie ria)

  (1) 呼叫一個可用的sessioncreateCriteria()方法建立Criteria物件,其中createCriteria()方法以被查詢的實體類型別作為引數。

  (2) 根據需要使用add函式設定各種criterion查詢條件,使用setProjection設定projection

  (3) 呼叫Criterialist或者scroll方法即執行查詢語句,檢索資料庫,把查詢結果返回放在ListScrollableResults中。

  (4) 讀取ListScrollableResults,即可取出查詢物件。

  Criteria介面在呼叫List或者Scroll方法時執行資料庫檢索,返回結果可以是以List形式或者ScrollableResults形式,與Query相比,少了iterate()方法執行返回iterator形式的結果。另外,與Query類似,Criteria也可以使用setFlushModesetCacheModesetTimeOut等設定各種Criteria查詢的環境,可以使用setFirstResult()setMaxResult()等方法設定檢索結果。

  下面介紹在Query中沒有的,但在Criteria中使用的主要的函式:

  (1) Criteria add(Criterion criterion)

  用於新增查詢條件,相當於設定HQL中的where從句。當有多個查詢條件時,可以逐個增加。例如:

  Criteria crit = session.createCriteria(Product.class);

          crit.add(Restrictions.gt("price",new Double(25.0)));

          crit.add(Restrictions.gt("name","Clothes"));

  List results = crit.list();

或者使用方法鏈程式設計風格:

  List results=session.createCriteria(Product.class)

   .add(Restrictions.gt("price",new Double(25.0)))

   .add(Restrictions.gt("name","Clothes"))

   .list();

  多個add相當於對查詢條件進行and操作,即要求同時滿足這些條件

  (2) Criteria addOrder(Order order)

  如果需要排序,可以使用CriteriaaddOrder()方法增加排序用的Order類。

  (3) Criteria createAlias(String associationPath, String alias) 

     Criteria createAlias(String associationPath, String alias, int joinType) 

List cats = sess.createCriteria(Cat.class)    .createAlias("kittens", "kt")    .createAlias("mate", "mt")    .add( Restrictions.eqProperty("kt.name", "mt.name") )    .list();

  用於設定連線查詢,第一種過載形式使用的是預設的內連線;第二種過載形式可以選擇連線方式。

  associationPath:屬性的路徑,使用點“.”作為分割符。例如,Basiccar持久化類中有集合屬性persons,而persons中的元素是持久化類Person,而Person類中有集合屬性clotheses,其中存有關聯物件clothes,如果要從Basiccar物件關聯到clothes物件,屬性路徑就寫成:persons.clotheses,使用點隔開。

  alias:關聯屬性的別名,後面可以使用這個別名來設定關聯條件。

  joinType:連線查詢時選擇的關聯方式。joinType可以是內連線CriteriaSpecification.INNER_JOIN(預設值)、全連線CriteriaSpecification.FULL_JOIN, 或者左連線CriteriaSpecification.LEFT_JOIN

  (4) Criteria createCriteria(String associationPath) 

     Criteria createCriteria(String associationPath, int joinType)  

  Criteria createCriteria(String associationPath, String alias)  

  Criteria createCriteria(String associationPath, String alias, int joinType)  

  建立一個指向主類關聯的實體的criteria查詢,在進行存在關聯關係的物件檢索時會用到。

  joinType可以指定關聯是內連線、左聯接還是全連線。alias則可以指定別名。

  返回值是被建立的子查詢。

  (5) Criteria setProjection(Projection projection)

  如果需要使用投影查詢、聚集函式等,可以按需要生成Projection類,然後使用CriteriasetProjection()方法,對返回結果進行某些列的投影或聚集運算。

  2. DetachedCriteria

  使用Criteria查詢需要當前有可用的session,但是,有時構造查詢語句時,並不一定能得到可用的session。例如,在分層的專案開發過程中,通常會在表現層,根據使用者選擇的條件,動態生成SQL語句,進行查詢。這個時候,表現層是得不到session的,但是它需要把構造好的查詢傳給業務層進行session查詢。DetachedCriteria就可以解決這個問題,即在表現層,應用程式使用DetachedCriteria來構造查詢條件,然後把這個detachedCriteria傳遞給業務層物件,讓業務層在session範圍內構造criteria查詢。所以,detachedCriteria在構造查詢時,session還不可用,detachedCriteria查詢面對的是遊離的POJO類,而Criteria查詢時面對的持久化物件,所以稱為detachedCriteria。以下是一個使用DetachedCriteria查詢的簡單例子。

  DetachedCriteria detachedCriteria= DetachedCriteria.forClass (BasicCar.class); detachedCriteria.add(Restrictions.eq("id", new Integer(1)));

  上面的程式碼片段先建立了一個DetachedCriteria的例項,然後只要在有可用的session時,使用它的getExecutableCriteria()方法,把這個可用的session關聯進來即可,它會返回一個在這個session內進行查詢的criteria類。程式碼如下所示:

  Criteria crit=detachedCriteria.getExecutableCriteria(session);

   List results = crit.list();

  DetachedCriteria 提供了4個靜態方法forClass(Class)forEntityName(Name)進行DetachedCriteria例項的建立。DetachedCriteria也提供了add(Criterion)addOrder(Order)setProjection(Projection)createAlias()createCriteria()等方法用於構造查詢及其返回結果,與Criteria提供的函式不同的是,DetachedCriteria類提供的函式返回也是DetachedCriteria 類。

  3. CriterionRetrictions

  CriterionCriteria介面的add()方法呼叫,作為查詢條件。內建的Criterion型別由Restrictions這個工廠類提供。實現Criterion介面的可以用來作為查詢條件的類包括ExpressionExampleJunction等。

  Criterion的類圖關係如圖8-2所示。

 

圖8-2  Criterion相關類圖

  4. ProjectionProjections

  Projection介面是Criteria查詢結果集的投影表示。內建的Projection類由Projections工廠類提供。實現projection介面的類包括AliasedProjectionDistinctProjectionListSimpleProjectionSQLProjection5個。Projection的類圖如圖8-3所示。

 

圖8-3  Projection相關類圖

  Projection介面被作為CriteriasetProjection()函式的引數,對查詢結果進行選擇某些屬性的投影,進行avgmaxmincountsum等聚集運算。

  Projections提供多種靜態方法來產生對查詢的結果進行各種運算的projection例項。

  表8-1列出了Projections提供的各種結果運算的函式,以及相應的HQL運算子。

表8-1  Projections的函式

意    思

Projections函式(重點)

HQL例子

1、計算平均值

avg(String?propertyName)

Select avg(o.property) from Object o

2、計算數目

count(String?propertyName)

Select count(o.property) from Object o

3、過濾相同值的屬性然後計算數目

countDistinct(String?propertyName)

Select count(distinct o.property) from Object o

4、過濾相同值的屬性

distinct(Projection?proj)

Select distinct o.property from Object o

5、按某個屬性分組

groupProperty(String?propertyName)

Criteria crit = session.createCriteria(BasicCar.class)

.setProjection(Projections.groupProperty("name"));

 

From Object o group by o.property

6、取物件的主鍵

id()

Select o.id from Object o

7、計算最大值

max(String?propertyName)

Select max(o.property) from Object o

8、計算最小值

min(String?propertyName)

Select min(o.property) from Object o

9、投影某個屬性

property(String?propertyName)

Select o.property from Object o

10、計算行數目

rowCount()

Select count(*) from Object o

11、計算總和

sum(String?propertyName)

Select sum(o.property) from Object o

5. Order(重點)

  Order類提供對Criteria查詢結果集的排序,其靜態函式生成升序或降序的Order類,被作為Criteria的引數傳給addOrder()方法。

  其主要函式有:

  static Order asc(String propertyName) 按降序排

static Order desc(String propertyName) 按升序排

List cats = sess.createCriteria(Cat.class)     .add( Restrictions.like("name", "F%")     .addOrder( Order.asc("name") )     .addOrder( Order.desc("age") )     .setMaxResults(50)     .list();

 

List cats = sess.createCriteria(Cat.class)    .add( Property.forName("name").like("F%") )    .addOrder( Property.forName("name").asc() )    .addOrder( Property.forName("age").desc() )    .setMaxResults(50)    .list();

 

8.1.2  使用Expression類和Example類設定查詢條件

  下面分別介紹Expression類和Example類的查詢條件。

  1Expression類(瞭解)

Expression類由Restrictions工廠類的各個設定條件的靜態方法產生。例如,Restrictions類中的gt(String propertyName, Object value)靜態方法,用於設定某個屬性等於某個值的查詢條件,返回的SimpleExpression相當於where propertyName='value'的條件。

方法

描述

Expression.eq

對應SQL“field=value”表示式

如:Expression.eq(“name”,”zx”);

Expression.allEq

方法的引數為一個Map型別物件,包含多個名/值對對應關係,相當於多個Expression.eq的疊加

Expression.gt

對應SQL“field>value”表示式

Expression.ge

對應SQL“field>=value”表示式

Expression.lt

對應SQL“field”表示式

Expression.le

對應SQL“field<=value”表示式

Expression.between

對應SQL語句的between表示式,如:查詢年齡在2127歲之間的使用者,可以寫成Expression.between(“age”,new Integer(21),new Integer(27));

Expression.like

對應SQL語句的”field like value”表示式

Expression.in

對應SQL語句的“field in(……)”表示式

Expression.eqProperty

用於比較兩個屬性值,對應”field=field”SQL表示式

Expression.gtProperty

用於比較兩個屬性值,對應”field>field”SQL表示式

Expression.geProperty

用於比較兩個屬性值,對應”field>=field”SQL表示式

Expression.ltProperty

用於比較兩個屬性值,對應”field表示式

Expression.leProperty

用於比較兩個屬性值,對應”field<=field”SQL表示式

Expression.and

對應SQL語句的And關係組合,如:Expression.and(Expression.eq(“name”,”zx”),Expression.eq(“sex”,”1”));

Expression.or

對應SQL語句的Or關係組合,如:Expression.or(Expression.eq(“name”,”zx”),Expression.eq(“name”,”zhaoxin”));

Expression.sql

作為補充這個方法提供了原生SQL語句查詢的支援,在執行時直接通過原生SQL語句進行限定,如:Expression.sql(“lower({alias}.name) like (?)”,“zhao%”,Hibernate.STRING) ;在執行時{ alias }將會由當前查詢所關聯的實體類名替換,()中的?將會由”zhao%”替換,並且型別由Hibernate.STRING指定。

 

 

  表8-2列出了Restrictions提供的各種條件設定,以及相應的HQL運算子。

表8-2  Restrictions的函式

意    思

Restrictions函式(重點)

HQL例子

1、查詢條件邏輯and運算

and(Criterion?lhs, Criterion?rhs)

From Object o where o.property1 = ? and o.property2=?

2、檢索在兩個數值之間的

between(String?propertyName, Object?lo,

 Object?hi)

From Object o where o.property between ? and ?

3、等於

eq(String?propertyName, Object?value)

eqProperty(String?propertyName, String?otherPropertyName)

Eg:   List cats = sess.createCriteria(Cat.class)       .createAlias("kittens", "kt")       .createAlias("mate", "mt")       .add( Restrictions.eqProperty("kt.name", "mt.name") )       .list();

From Object o where 

o.property=?

4、大於等於

ge(String?propertyName, Object?value)

geProperty(String?propertyName, String?otherPropertyName)

From Object o where 

o.property>=?

5、大於

gt(String?propertyName, Object?value)

gtProperty(String?propertyName, String?otherPropertyName)

From Object o where 

o.property>?

6、主鍵等於

idEq(Object?value)

Criteria crit = session.createCriteria(BasicCar.class)

.add( Expression.idEq(new Long(1)) );

 

From Object o where o.id=?

7、字串匹配,不區分大小寫

islike(String?propertyName, Object?value)

islike(String?propertyName, String?value, MatchMode?matchMode)

 

Criteria crit = session.createCriteria(BasicCar.class)

.add(Restrictions.islike("name","a", MatchMode.END));

 

List cats = sess.createCriteria(Cat.class)    .add( Restrictions.like("name", "Fritz%") )

 

From Object o where lower 

(o.property) like ??

(續表)   

意    思

Restrictions函式

HQL例子

8、範圍運算

in(String?propertyName, Collection?values)

in(String?propertyName, Object[]?values)

From Object o where o.property in(‘a’,’b’…)

  .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )

9、檢查物件的一個集合屬性是否為空,也就是在多對多或多對一雙向關聯中,“方對應的方為空,沒有關聯的

isEmpty(String?propertyName)

From Object o where 

o.properties is empty

10、檢查物件的一個集合屬性是否不為空

isNotEmpty(String?propertyName)

From Object o where 

o.properties is not empty

11、一個屬性是否不為空

isNotNull(String?propertyName)

From Object o where o.property is not null

12、一個屬性是否為空

isNull(String?propertyName)

 

Criteria crit = session.createCriteria(BasicCar.class)

.add(Restrictions.isNull("name"));

 

From Object o where o.property 

is null

13、小於等於

le(String?propertyName, Object?value)

leProperty(String?propertyName, String?otherPropertyName)

From Object o where 

o.property<=?

14、字串匹配

like(String?propertyName, Object?value)

like(String?propertyName, String?value, MatchMode?matchMode)

Criteria crit = session.createCriteria(BasicCar.class)

.add(Restrictions.like("name","A%"));

 

From Object o where o.property 

like ‘??’

15、小於

lt(String?propertyName, Object?value)

ltProperty(String?propertyName, String?otherPropertyName)

From Object o where 

o.property