Hibernate標準查尋Criteria 用法總結

現在對 HibernateCriteria 的用法進行總結: 
         Hibernate 
設計了 CriteriaSpecification 作爲 Criteria 的父接口,下面提供了 CriteriaDetachedCriteria  
          Criteria 
 DetachedCriteria 的主要區別在於創建的形式不一樣, Criteria 是在線的,所以它是由 Hibernate Session 進行創建的;而 DetachedCriteria 是離線的,創建時無需SessionDetachedCriteria 提供了 2 個靜態方法forClass(Class)  forEntityName(Name)進行DetachedCriteria 實例的創建。 Spring 的框架提供了getHibernateTemplate 
().findByCriteria(detachedCriteria
方法可以很方便地根據DetachedCriteria 來返回查詢結 
果。 
          Criteria 
 DetachedCriteria 均可使用 Criterion  Projection 設置查詢條件。可以設 
 FetchMode聯合查詢抓取的模式 ) ,設置排序方式。對於 Criteria 還可以設置FlushModel(沖刷 Session 的方式)和 LockMode (數據庫鎖模式)。 
下面對 Criterion  Projection 進行詳細說明。 
          Criterion 
 Criteria 的查詢條件。Criteria 提供了 add(Criterion criterion) 方法來 
添加查詢條件。 
          Criterion 
接口的主要實現包括: Example  Junction  SimpleExpression 。而Junction 的實際使用是它的兩個子類 conjunction  disjunction ,分別是使用 AND  OR 操作符進行來聯結查詢條件集合。 
          Criterion 
的實例可以通過 Restrictions 工具類來創建,Restrictions 提供了大量的靜態方法,如 eq (等於)、 ge (大於等於)、 between 等來方法的創建 Criterion 查詢條件(SimpleExpression 實例)。除此之外, Restrictions 還提供了方法來創建 conjunction disjunction 實例,通過往該實例的 add(Criteria) 方法來增加查詢條件形成一個查詢條件集合 
 
          
至於 Example 的創建有所不同, Example 本身提供了一個靜態方法 create(Object 
entity) 
,即根據一個對象(實際使用中一般是映射到數據庫的對象)來創建。然後可以設置一些過濾條件:

Example exampleUser =Example.create(u)

       .ignoreCase()                    // 忽略大小寫

        .enableLike(MatchMode.ANYWHERE); //  String 類型的屬性,無論在那裏值在那裏都匹配。相當於 %value%

          Project 主要是讓 Criteria 能夠進行報表查詢,並可以實現分組。 Project 主要有 
SimpleProjection 
 ProjectionList  Property 三個實現。其中 SimpleProjection  
ProjectionList 
的實例化是由內建的 Projections 來完成,如提供的 avg  count  max  
min 
 sum 可以讓開發者很容易對某個字段進行統計查詢。 
          Property 
是對某個字段進行查詢條件的設置,如通過Porperty.forName(“color”).in 
(new String[]{“black”,”red”,”write”}); 
則可以創建一個 Project 實例。通過 
criteria 
 add(Project) 方法加入到查詢條件中去。 
          
使用 Criteria 進行查詢,主要要清晰的是 Hibernate 提供了那些類和方法來滿足開發中查詢條件的創建和組裝,下面介紹幾種用法:

1. 創建一個Criteria 實例


org.hibernate.Criteria
接口表示特定持久類的一個查詢。Session Criteria實例的工廠。

   1:  Criteria crit = sess.createCriteria(Cat.class);

   2:  crit.setFirstResult(1);

   3:  crit.setMaxResults(50);

   4:  List cats = crit.list();


2. 
限制結果集內容


一個單獨的查詢條件是org.hibernate.criterion.Criterion 接口的一個實例。 
org.hibernate.criterion.Restrictions
 定義了獲得某些內置Criterion類型的工廠方法。

   1:  List cats = sess.createCriteria(Cat.class)

   2:      .add( Restrictions.like("name""Fritz%") )

   3:      .add( Restrictions.between("weight"minWeightmaxWeight) )

   4:      .list();


約束可以按邏輯分組。

   1:  List cats = sess.createCriteria(Cat.class)

   2:      .add( Restrictions.like("name""Fritz%") ) 

   3:      .add( Restrictions.or

   4:               Restrictions.eq( "age"new Integer(0) ),

   5:               Restrictions.isNull("age")

   6:       )

   7:  ).list();

   8:   

   9:  List cats = sess.createCriteria(Cat.class)

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

  11:      .add( Restrictions.disjunction()

  12:            .add( Restrictions.isNull("age") )

  13:            .add( Restrictions.eq("age"new Integer(0) ) )

  14:            .add( Restrictions.eq("age"new Integer(1) ) )

  15:            .add( Restrictions.eq("age"new Integer(2) ) )

  16:        )

  17:   ).list();


Hibernate
提供了相當多的內置criterion類型(Restrictions 子類), 但是尤其有用的是可以允許 
你直接使用SQL

   1:  List cats = sess.createCriteria(Cat.class)

   2:      .add( Restrictions.sql("lower({alias}.name) like lower(?)""Fritz%",Hibernate.STRING) )

   3:      .list();


{alias}
佔位符應當被替換爲被查詢實體的列別名。 
Property
實例是獲得一個條件的另外一種途徑。你可以通過調用Property.forName() 創建一個Property

   1:  Property age = Property.forName("age");

   2:  List cats = sess.createCriteria(Cat.class)

   3:      .add( Restrictions.disjunction()

   4:         .add( age.isNull() )

   5:         .add( age.eqnew Integer(0) ) )

   6:         .add( age.eqnew Integer(1) ) )

   7:         .add( age.eqnew Integer(2) ) )

   8:        )

   9:     ) .add( Property.forName("name").innew String[] { "Fritz""Izi""Pk" } ) )

  10:     .list();

 

3. 結果集排序

你可以使用org.hibernate.criterion.Order來爲查詢結果排序。

   1:  List cats = sess.createCriteria(Cat.class)

   2:      .add( Restrictions.like("name""F%")

   3:      .addOrder( Order.asc("name") )

   4:      .addOrder( Order.desc("age") )

   5:      .setMaxResults(50)

   6:      .list();

   7:   

   8:  List cats = sess.createCriteria(Cat.class)

   9:      .add( Property.forName("name").like("F%") )

  10:      .addOrder( Property.forName("name").asc() )

  11:      .addOrder( Property.forName("age").desc() )

  12:      .setMaxResults(50)

  13:      .list();

 

4. 關聯

你可以使用createCriteria()非常容易的在互相關聯的實體間建立 約束。

   1:  List cats = sess.createCriteria(Cat.class)

   2:      .add( Restrictions.like("name""F%")

   3:      .createCriteria("kittens")

   4:      .add( Restrictions.like("name""F%")

   5:      .list();


注意第二個 createCriteria()返回一個新的 Criteria實例,該實例引用kittens 集合中的元素。 
接下來,替換形態在某些情況下也是很有用的。

   1:  List cats = sess.createCriteria(Cat.class)

   2:      .createAlias("kittens""kt")

   3:      .createAlias("mate""mt")

   4:      .add( Restrictions.eqProperty("kt.name""mt.name") )

   5:      .list();


(createAlias()
並不創建一個新的 Criteria實例。
Cat
實例所保存的之前兩次查詢所返回的kittens集合是 沒有被條件預過濾的。如果你希望只獲得符合條件的kittens 你必須使用returnMaps()

   1:  List cats = sess.createCriteria(Cat.class)

   2:      .createCriteria("kittens""kt")

   3:      .add( Restrictions.eq("name""F%") )

   4:      .returnMaps()

   5:      .list();

   6:   

   7:  Iterator iter = cats.iterator();

   8:  while iter.hasNext() ) {

   9:      Map map = (Map) iter.next();

  10:      Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);

  11:      Cat kitten = (Cat) map.get("kt");

  12:  }

 

5. 動態關聯抓取

你可以使用setFetchMode()在運行時定義動態關聯抓取的語義。

   1:  List cats = sess.createCriteria(Cat.class)

   2:      .add( Restrictions.like("name""Fritz%") )

   3:      .setFetchMode("mate"FetchMode.EAGER)

   4:      .setFetchMode("kittens"FetchMode.EAGER)

   5:      .list();


這個查詢可以通過外連接抓取matekittens

6. 查詢示例

org.hibernate.criterion.Example類允許你通過一個給定實例 構建一個條件查詢。

   1:  Cat cat = new Cat();

   2:  cat.setSex('F');

   3:  cat.setColor(Color.BLACK);

   4:   

   5:  List results = session.createCriteria(Cat.class)

   6:      .add( Example.create(cat) )

   7:      .list();


版本屬性、標識符和關聯被忽略。默認情況下值爲null的屬性將被排除。 
可以自行調整Example使之更實用。

   1:  Example example = Example.create(cat)

   2:      .excludeZeroes()     //exclude zero valued properties

   3:      .excludeProperty("color"//exclude the property named "color"

   4:      .ignoreCase()       //perform case insensitive string comparisons

   5:      .enableLike();       //use like for string comparisons

   6:   

   7:  List results = session.createCriteria(Cat.class)

   8:      .add(example)

   9:      .list();


甚至可以使用examples在關聯對象上放置條件。

   1:  List results = session.createCriteria(Cat.class)

   2:      .add( Example.create(cat) )

   3:      .createCriteria("mate")

   4:      .add( Example.createcat.getMate() ) )

   5:      .list();

 

7. 投影(Projections)、聚合(aggregation)和分組(grouping

org.hibernate.criterion.Projections Projection 的實例工廠。我們通過調用 
setProjection()
應用投影到一個查詢。

   1:  List results = session.createCriteria(Cat.class)

   2:      .setProjection( Projections.rowCount() )

   3:      .add( Restrictions.eq("color", Color.BLACK) )

   4:      .list();

   5:   

   6:  List results = session.createCriteria(Cat.class)

   7:      .setProjection( Projections.projectionList()

   8:          .add( Projections.rowCount() )

   9:          .add( Projections.avg("weight") )

  10:          .add( Projections.max("weight") )

  11:          .add( Projections.groupProperty("color") )

  12:      ).list();


在一個條件查詢中沒有必要顯式的使用 "group by" 。某些投影類型就是被定義爲 分組投影,他們也出現在SQLgroup by子句中。可以選擇把一個別名指派給一個投影,這樣可以使投影值被約束或排序所引用。

下面是兩種不同的實現方式:

   1:  List results = session.createCriteria(Cat.class)

   2:      .setProjection( Projections.aliasProjections.groupProperty("color"), "colr" ) )

   3:      .addOrder( Order.asc("colr") )

   4:      .list();

   5:   

   6:  List results = session.createCriteria(Cat.class)

   7:      .setProjection( Projections.groupProperty("color").as("colr") )

   8:      .addOrder( Order.asc("colr") )

   9:      .list();


alias()
as()方法簡便的將一個投影實例包裝到另外一個 別名的Projection實例中。簡而言之, 
當你添加一個投影到一個投影列表中時 你可以爲它指定一個別名:

   1:  List results = session.createCriteria(Cat.class)

   2:      .setProjection( Projections.projectionList()

   3:          .add( Projections.rowCount(), "catCountByColor" )

   4:          .add( Projections.avg("weight"), "avgWeight" )

   5:          .add( Projections.max("weight"), "maxWeight" )

   6:          .add( Projections.groupProperty("color"), "color" )

   7:      )

   8:      .addOrder( Order.desc("catCountByColor") )

   9:      .addOrder( Order.desc("avgWeight") )

  10:      .list();

  11:   

  12:  List results = session.createCriteria(Domestic.class"cat")

  13:      .createAlias("kittens""kit")

  14:      .setProjection( Projections.projectionList()

  15:          .add( Projections.property("cat.name"), "catName" )

  16:          .add( Projections.property("kit.name"), "kitName" )

  17:      )

  18:      .addOrder( Order.asc("catName") )

  19:      .addOrder( Order.asc("kitName") )

  20:      .list();


也可以使用Property.forName()來表示投影:

   1:  List results = session.createCriteria(Cat.class)

   2:      .setProjection( Property.forName("name") )

   3:      .add( Property.forName("color").eq(Color.BLACK) )

   4:      .list();

   5:   

   6:  List results = session.createCriteria(Cat.class)

   7:      .setProjection( Projections.projectionList()

   8:          .add( Projections.rowCount().as("catCountByColor") )

   9:          .add( Property.forName("weight").avg().as("avgWeight") )

  10:          .add( Property.forName("weight").max().as("maxWeight") )

  11:          .add( Property.forName("color").group().as("color" )

  12:      )

  13:      .addOrder( Order.desc("catCountByColor") )

  14:      .addOrder( Order.desc("avgWeight") )

  15:      .list();

 

8. 離線(detached)查詢和子查詢

DetachedCriteria類使你在一個session範圍之外創建一個查詢,並且可以使用任意的 Session來執行它。

   1:  DetachedCriteria query = DetachedCriteria.forClass(Cat.class)

   2:      .add( Property.forName("sex").eq('F') );

   3:  //創建一個Session

   4:  Session session = HibernateUtil.getSession();

   5:  Transaction txn = session.beginTransaction();

   6:  List results = query.getExecutableCriteria(session).setMaxResults(100).list();

   7:  txn.commit();

   8:  session.close();


DetachedCriteria
也可以用以表示子查詢。條件實例包含子查詢可以通過 Subqueries或者Property獲得。

   1:  DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)

   2:          .setProjection(Property.forName("weight").avg());

   3:  session.createCriteria(Cat.class)

   4:          .add(Property.forName("weight").gt(avgWeight)).list();

   5:  DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)

   6:          .setProjection(Property.forName("weight"));

   7:  session.createCriteria(Cat.class)

   8:          .add(Subqueries.geAll("weight", weights)).list();


相互關聯的子查詢也是有可能的:

   1:  DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class"cat2")

   2:      .setProjection( Property.forName("weight").avg() )

   3:      .add( Property.forName("cat2.sex").eqProperty("cat.sex") );

   4:   

   5:  session.createCriteria(Cat.class"cat")

   6:      .add( Property.forName("weight).gt(avgWeightForSex) )

   7:      .list();

 

補充:

   1:  criteria.add(Expression.eq("status",new Integer(status)));

   2:  criteria.add(Expression.in("status"optParm.getQueryStatus()));

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章