Hibernate---Criteria
具有一個直觀的、可擴展的條件查詢API是Hibernate的特色。
15.1
. 創建一個Criteria 實例
org.hibernate.Criteria接口表示特定持久類的一個查詢。Session是 Criteria實例的工廠。
Criteria crit = sess.createCriteria(Cat.
class
);
crit.setMaxResults(
50
);
List cats = crit.list();
15.2
. 限制結果集內容
一個單獨的查詢條件是org.hibernate.criterion.Criterion 接口的一個實例。org.hibernate.criterion.Restrictions類 定義了獲得某些內置Criterion類型的工廠方法。
List cats = sess.createCriteria(Cat.
class
)
.add( Restrictions.like(
"name"
,
"Fritz%"
) )
.add( Restrictions.between(
"weight"
, minWeight, maxWeight) )
.list();
約束可以按邏輯分組。
List cats = sess.createCriteria(Cat.
class
)
.add( Restrictions.like(
"name"
,
"Fritz%"
) )
.add( Restrictions.or(
Restrictions.eq(
"age"
,
new
Integer(
0
) ),
Restrictions.isNull(
"age"
)
) )
.list();
List cats = sess.createCriteria(Cat.
class
)
.add( Restrictions.in(
"name"
,
new
String[] {
"Fritz"
,
"Izi"
,
"Pk"
} ) )
.add( Restrictions.disjunction()
.add( Restrictions.isNull(
"age"
) )
.add( Restrictions.eq(
"age"
,
new
Integer(
0
) ) )
.add( Restrictions.eq(
"age"
,
new
Integer(
1
) ) )
.add( Restrictions.eq(
"age"
,
new
Integer(
2
) ) )
) )
.list();
Hibernate提供了相當多的內置criterion類型(Restrictions 子類), 但是尤其有用的是可以允許你直接使用SQL。
List cats = sess.createCriteria(Cat.
class
)
.add( Restrictions.sql(
"lower({alias}.name) like lower(?)"
,
"Fritz%"
, Hibernate.STRING) )
.list();
{alias}佔位符應當被替換爲被查詢實體的列別名。
Property實例是獲得一個條件的另外一種途徑。你可以通過調用Property.forName() 創建一個Property。
Property age = Property.forName(
"age"
);
List cats = sess.createCriteria(Cat.
class
)
.add( Restrictions.disjunction()
.add( age.isNull() )
.add( age.eq(
new
Integer(
0
) ) )
.add( age.eq(
new
Integer(
1
) ) )
.add( age.eq(
new
Integer(
2
) ) )
) )
.add( Property.forName(
"name"
).in(
new
String[] {
"Fritz"
,
"Izi"
,
"Pk"
} ) )
.list();
15.3
. 結果集排序
你可以使用org.hibernate.criterion.Order來爲查詢結果排序。
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();
15.4
. 關聯
你可以使用createCriteria()非常容易的在互相關聯的實體間建立 約束。
List cats = sess.createCriteria(Cat.
class
)
.add( Restrictions.like(
"name"
,
"F%"
)
.createCriteria(
"kittens"
)
.add( Restrictions.like(
"name"
,
"F%"
)
.list();
注意第二個 createCriteria()返回一個新的 Criteria實例,該實例引用kittens 集合中的元素。
接下來,替換形態在某些情況下也是很有用的。
List cats = sess.createCriteria(Cat.
class
)
.createAlias(
"kittens"
,
"kt"
)
.createAlias(
"mate"
,
"mt"
)
.add( Restrictions.eqProperty(
"kt.name"
,
"mt.name"
) )
.list();
(createAlias()並不創建一個新的 Criteria實例。)
Cat實例所保存的之前兩次查詢所返回的kittens集合是 沒有被條件預過濾的。如果你希望只獲得符合條件的kittens, 你必須使用returnMaps()。
List cats = sess.createCriteria(Cat.
class
)
.createCriteria(
"kittens"
,
"kt"
)
.add( Restrictions.eq(
"name"
,
"F%"
) )
.returnMaps()
.list();
Iterator iter = cats.iterator();
while
( iter.hasNext() ) {
Map map = (Map) iter.next();
Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
Cat kitten = (Cat) map.get(
"kt"
);
}
15.5
. 動態關聯抓取
你可以使用setFetchMode()在運行時定義動態關聯抓取的語義。
List cats = sess.createCriteria(Cat.
class
)
.add( Restrictions.like(
"name"
,
"Fritz%"
) )
.setFetchMode(
"mate"
, FetchMode.EAGER)
.setFetchMode(
"kittens"
, FetchMode.EAGER)
.list();
這個查詢可以通過外連接抓取mate和kittens。 查看第
19.1
節 “ 抓取策略(Fetching strategies) ”可以獲得更多信息。
15.6
. 查詢示例
org.hibernate.criterion.Example類允許你通過一個給定實例 構建一個條件查詢。
Cat cat =
new
Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List results = session.createCriteria(Cat.
class
)
.add( Example.create(cat) )
.list();
版本屬性、標識符和關聯被忽略。默認情況下值爲
null
的屬性將被排除。
你可以自行調整Example使之更實用。
Example example = Example.create(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 = session.createCriteria(Cat.
class
)
.add(example)
.list();
你甚至可以使用examples在關聯對象上放置條件。
List results = session.createCriteria(Cat.
class
)
.add( Example.create(cat) )
.createCriteria(
"mate"
)
.add( Example.create( cat.getMate() ) )
.list();
15.7
. 投影(Projections)、聚合(aggregation)和分組(grouping)
org.hibernate.criterion.Projections是 Projection 的實例工廠。我們通過調用 setProjection()應用投影到一個查詢。
List results = session.createCriteria(Cat.
class
)
.setProjection( Projections.rowCount() )
.add( Restrictions.eq(
"color"
, Color.BLACK) )
.list();
List results = session.createCriteria(Cat.
class
)
.setProjection( Projections.projectionList()
.add( Projections.rowCount() )
.add( Projections.avg(
"weight"
) )
.add( Projections.max(
"weight"
) )
.add( Projections.groupProperty(
"color"
) )
)
.list();
在一個條件查詢中沒有必要顯式的使用
"group by"
。某些投影類型就是被定義爲 分組投影,他們也出現在SQL的group by子句中。
你可以選擇把一個別名指派給一個投影,這樣可以使投影值被約束或排序所引用。下面是兩種不同的實現方式:
List results = session.createCriteria(Cat.
class
)
.setProjection( Projections.alias( Projections.groupProperty(
"color"
),
"colr"
) )
.addOrder( Order.asc(
"colr"
) )
.list();
List results = session.createCriteria(Cat.
class
)
.setProjection( Projections.groupProperty(
"color"
).as(
"colr"
) )
.addOrder( Order.asc(
"colr"
) )
.list();
alias()和as()方法簡便的將一個投影實例包裝到另外一個 別名的Projection實例中。簡而言之,當你添加一個投影到一個投影列表中時 你可以爲它指定一個別名:
List results = session.createCriteria(Cat.
class
)
.setProjection( Projections.projectionList()
.add( Projections.rowCount(),
"catCountByColor"
)
.add( Projections.avg(
"weight"
),
"avgWeight"
)
.add( Projections.max(
"weight"
),
"maxWeight"
)
.add( Projections.groupProperty(
"color"
),
"color"
)
)
.addOrder( Order.desc(
"catCountByColor"
) )
.addOrder( Order.desc(
"avgWeight"
) )
.list();
List results = session.createCriteria(Domestic.
class
,
"cat"
)
.createAlias(
"kittens"
,
"kit"
)
.setProjection( Projections.projectionList()
.add( Projections.property(
"cat.name"
),
"catName"
)
.add( Projections.property(
"kit.name"
),
"kitName"
)
)
.addOrder( Order.asc(
"catName"
) )
.addOrder( Order.asc(
"kitName"
) )
.list();
你也可以使用Property.forName()來表示投影.......
更多請參閱http://www.360watcher.net/html/35/655.htm
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.