最近在項目中使用 Spring 和 Hibernate 進行開發有感於 Criteria 比較好用在查詢方法設計上可以靈活的根據 Criteria 的特點來方便地進行查詢條件的組裝現在對 Hibernate的Criteria的用法進行總結
Hibernate 設計了 CriteriaSpecification 作為 Criteria 的父接口下面提供了 Criteria和DetachedCriteria
Criteria 和 DetachedCriteria 的主要區別在於創建的形式不一樣 Criteria 是在線的所以它是由 Hibernate Session 進行創建的而 DetachedCriteria 是離線的創建時無需SessionDetachedCriteria 提供了 個靜態方法 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 和 Simpl********** 而Junction 的實際使用是它的兩個子類 conjunction 和 disjunction 分別是使用 AND 和 OR 操作符進行來聯結查詢條件集合
Criterion 的實例可以通過 Restrictions 工具類來創建Restrictions 提供了大量的靜態方法如 eq (等於) ge (大於等於) between 等來方法的創建 Criterion 查詢條件(Simpl********** 實例)除此之外 Restrictions 還提供了方法來創建 conjunction 和disjunction 實例通過往該實例的 add(Criteria) 方法來增加查詢條件形成一個查詢條件集合
至於 Example 的創建有所不同 Example 本身提供了一個靜態方法 create(Objectentity) 即根據一個對象(實際使用中一般是映射到數據庫的對象)來創建然後可以設置一些過濾條件
Example exampleUser =Examplecreate(u)
ignoreCase() // 忽略大小寫
enableLike(MatchModeANYWHERE);
Project 主要是讓 Criteria 能夠進行報表查詢並可以實現分組 Project 主要有SimpleProjection ProjectionList 和 Property 三個實現其中SimpleProjection 和ProjectionList 的實例化是由內建的 Projections 來完成如提供的 avg count max min sum 可以讓開發者很容易對某個字段進行統計查詢
Property 是對某個字段進行查詢條件的設置如通過PorpertyforName(color)in(new String[]{blackredwrite}); 則可以創建一個 Project 實例通過criteria 的 add(Project) 方法加入到查詢條件中去
使用 Criteria 進行查詢主要要清晰的是 Hibernate 提供了那些類和方法來滿足開發中查詢條件的創建和組裝下面介紹幾種用法
創建一個Criteria 實例
orghibernateCriteria接口表示特定持久類的一個查詢Session是 Criteria實例的工廠
Criteria crit = sesscreateCriteria(Catclass);
critsetMaxResults();
List cats = critlist();
限制結果集內容
一個單獨的查詢條件是orghibernatecriterionCriterion 接口的一個實例
orghibernatecriterionRestrictions類 定義了獲得某些內置Criterion類型的工廠方法
List cats = sesscreateCriteria(Catclass)
add( Restrictionslike(name Fritz%) )
add( Restrictionsbetween(weight minWeight maxWeight) )
list();
約束可以按邏輯分組
orghibernatecriterionRestrictions類 定義了獲得某些內置Criterion類型的工廠方法
List cats = sesscreateCriteria(Catclass)
add( Restrictionslike(name Fritz%) )
add( Restrictionsbetween(weight minWeight maxWeight) )
list();
Hibernate提供了相當多的內置criterion類型(Restrictions 子類) 但是尤其有用的是可以允許你直接使用SQL
List cats = sesscreateCriteria(Catclass)
add( Restrictionssql(lower({alias}name) like lower(?) Fritz%
HibernateSTRING) )
list();
{alias}占位符應當被替換為被查詢實體的列別名
Property實例是獲得一個條件的另外一種途徑你可以通過調用PropertyforName() 創建一個Property
Property age = PropertyforName(age);
List cats = sesscreateCriteria(Catclass)
add( Restrictionsdisjunction()
add( ageisNull() )
add( ageeq( new Integer() ) )
add( ageeq( new Integer() ) )
add( ageeq( new Integer() ) )
) )
add( PropertyforName(name)in( new String[] { Fritz Izi Pk } ) )
list();
結果集排序
你可以使用orghibernatecriterionOrder來為查詢結果排序
List cats = sesscreateCriteria(Catclass)
add( Restrictionslike(name F%)
addOrder( Orderasc(name) )
addOrder( Orderdesc(age) )
setMaxResults()
list();
List cats = sesscreateCriteria(Catclass)
add( PropertyforName(name)like(F%) )
addOrder( PropertyforName(name)asc() )
addOrder( PropertyforName(age)desc() )
setMaxResults()
list();
關聯
你可以使用createCriteria()非常容易的在互相關聯的實體間建立約束
List cats = sesscreateCriteria(Catclass)
add( Restrictionslike(name F%)
createCriteria(kittens)
add( Restrictionslike(name F%)
list();
注意第二個 createCriteria()返回一個新的 Criteria實例該實例引用kittens 集合中的元素接下來替換形態在某些情況下也是很有用的
List cats = sesscreateCriteria(Catclass)
createAlias(kittens kt)
createAlias(mate mt)
add( RestrictionseqProperty(ktname mtname) )
list();
(createAlias()並不創建一個新的 Criteria實例)
Cat實例所保存的之前兩次查詢所返回的kittens集合是 沒有被條件預過濾的如果你希望只獲得符合條件的kittens 你必須使用returnMaps()
List cats = sesscreateCriteria(Catclass)
createCriteria(kittens kt)
add( Restrictionseq(name F%) )
returnMaps()
list();
Iterator iter = erator();
while ( iterhasNext() ) {
Map map = (Map) iternext();
Cat cat = (Cat) mapget(CriteriaROOT_ALIAS);
Cat kitten = (Cat) mapget(kt);
}
動態關聯抓取
你可以使用setFetchMode()在運行時定義動態關聯抓取的語義
List cats = sesscreateCriteria(Catclass)
add( Restrictionslike(name Fritz%) )
setFetchMode(mate FetchModeEAGER)
setFetchMode(kittens FetchModeEAGER)
list();
這個查詢可以通過外連接抓取mate和kittens
查詢示例
orghibernatecriterionExample類允許你通過一個給定實例 構建一個條件查詢
Cat cat = new Cat();
catsetSex(F);
catsetColor(ColorBLACK);
List results = sessioncreateCriteria(Catclass)
add( Examplecreate(cat) )
list();
版本屬性標識符和關聯被忽略默認情況下值為null的屬性將被排除可以自行調整Example使之更實用
Example example = Examplecreate(cat)
excludeZeroes() //exclude zero valued properties
excludeProperty(color) //exclude the property named color
ignoreCase() //perform case insensitive string comparisons
enableLike(); //use like for string comparisons
List results = sessioncreateCriteria(Catclass)
add(example)
list();
甚至可以使用examples在關聯對象上放置條件
List results = sessioncreateCriteria(Catclass)
add( Examplecreate(cat) )
createCriteria(mate)
add( Examplecreate( catgetMate() ) )
list();
投影(Projections)聚合(aggregation)和分組(grouping)
orghibernatecriterionProjections是 Projection 的實例工廠我們通過調用setProjection()應用投影到一個查詢
List results = sessioncreateCriteria(Catclass)
setProjection( ProjectionsrowCount() )
add( Restrictionseq(color ColorBLACK) )
list();
List results = sessioncreateCriteria(Catclass)
setProjection( ProjectionsprojectionList()
add( ProjectionsrowCount() )
add( Projectionsavg(weight) )
add( Projectionsmax(weight) )
add( ProjectionsgroupProperty(color) )
)
list();
在一個條件查詢中沒有必要顯式的使用 group by 某些投影類型就是被定義為 分組投影他們也出現在SQL的group by子句中
可以選擇把一個別名指派給一個投影這樣可以使投影值被約束或排序所引用下面是兩種不同的實現方式
List results = sessioncreateCriteria(Catclass)
setProjection( Projectionsalias( ProjectionsgroupProperty(color) colr ) )
addOrder( Orderasc(colr) )
list();
List results = sessioncreateCriteria(Catclass)
setProjection( ProjectionsgroupProperty(color)as(colr) )
addOrder( Orderasc(colr) )
list();
alias()和as()方法簡便的將一個投影實例包裝到另外一個 別名的Projection實例中簡而言之當你添加一個投影到一個投影列表中時 你可以為它指定一個別名
List results = sessioncreateCriteria(Catclass)
setProjection( ProjectionsprojectionList()
add( ProjectionsrowCount() catCountByColor )
add( Projectionsavg(weight) avgWeight )
add( Projectionsmax(weight) maxWeight )
add( ProjectionsgroupProperty(color) color )
)
addOrder( Orderdesc(catCountByColor) )
addOrder( Orderdesc(avgWeight) )
list();
List results = sessioncreateCriteria(Domesticclass cat)
createAlias(kittens kit)
setProjection( ProjectionsprojectionList()
add( Projectionsproperty(catname) catName )
add( Projectionsproperty(kitname) kitName )
)
addOrder( Orderasc(catName) )
addOrder( Orderasc(kitName) )
list();
也可以使用PropertyforName()來表示投影
List results = sessioncreateCriteria(Catclass)
setProjection( PropertyforName(name) )
add( PropertyforName(color)eq(ColorBLACK) )
list();
List results = sessioncreateCriteria(Catclass)
setProjection( ProjectionsprojectionList()
add( ProjectionsrowCount()as(catCountByColor) )
add( PropertyforName(weight)avg()as(avgWeight) )
add( PropertyforName(weight)max()as(maxWeight) )
add( PropertyforName(color)group()as(color )
)
addOrder( Orderdesc(catCountByColor) )
addOrder( Orderdesc(avgWeight) )
list();
離線(detached)查詢和子查詢
DetachedCriteria類使你在一個session范圍之外創建一個查詢並且可以使用任意的 Session來執行它
DetachedCriteria query = DetachedCriteriaforClass(Catclass)
add( PropertyforName(sex)eq(F) );
//創建一個Session
Session session = ;
Transaction txn = sessionbeginTransaction();
List results = querygetExecutableCriteria(session)setMaxResults()list();
mit();
sessionclose();
DetachedCriteria也可以用以表示子查詢條件實例包含子查詢可以通過 Subqueries或者Property獲得
DetachedCriteria avgWeight = DetachedCriteriaforClass(Catclass)
setProjection( PropertyforName(weight)avg() );
sessioncreateCriteria(Catclass)
add( PropertyforName(weight)gt(avgWeight) )
list();
DetachedCriteria weights = DetachedCriteriaforClass(Catclass)
setProjection( PropertyforName(weight) );
sessioncreateCriteria(Catclass)
add( SubqueriesgeAll(weight
相互關聯的子查詢也是有可能的
DetachedCriteria avgWeightForSex = DetachedCriteriaforClass(Catclass cat)
setProjection( PropertyforName(weight)avg() )
add( PropertyforName(catsex)eqProperty(catsex) );
sessioncreateCriteria(Catclass cat)
add( PropertyforName(
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28125.html