Criteria Query
Criteria Query通過面向對象化的設計,將數據查詢條件封裝為一個對象。簡單來
講,Criteria Query可以看作是傳統SQL的對象化表示,如:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Expression.eq("name","Erica"));
criteria.add(Expression.eq("sex",new Integer(1)));
這里的criteria 實例實際上是SQL “Select * from t_user where
name=’Erica’ and sex=1”的封裝(我們可以打開Hibernate 的show_sql 選項,
以觀察Hibernate在運行期生成的SQL語句)。
Hibernate 在運行期會根據Criteria 中指定的查詢條件(也就是上面代碼中通過
criteria.add方法添加的查詢表達式)生成相應的SQL語句。
這種方式的特點是比較符合Java 程序員的編碼習慣,并且具備清晰的可讀性。正因
為此,不少ORM實現中都提供了類似的實現機制(如Apache OJB)。
對于Hibernate的初學者,特別是對SQL了解有限的程序員而言,Criteria Query
無疑是上手的極佳途徑,相對HQL,Criteria Query提供了更易于理解的查詢手段,借
助IDE的Coding Assist機制,Criteria的使用幾乎不用太多的學習。
Criteria 查詢表達式
Criteria 本身只是一個查詢容器,具體的查詢條件需要通過Criteria.add
方法添加到Criteria實例中。
如前例所示,Expression 對象具體描述了查詢條件。針對SQL 語法,
Expression提供了對應的查詢限定機制,包括:
方法 描述
Expression.eq 對應SQL“field = value”表達式。
如Expression.eq("name","Erica")
Expression.allEq 參數為一個Map對象,其中包含了多個屬性-值對
應關系。相當于多個Expression.eq關系的疊加。
Expression.gt 對應SQL中的 “field > value ” 表達式
Hibernate Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
Expression.ge 對應SQL中的 “field >= value” 表達式
Expression.lt 對應SQL中的 “field < value” 表達式
Expression.le 對應SQL中的 “field <= value” 表達式
Expression.between 對應SQL中的 “between” 表達式
如下面的表達式表示年齡(age)位于13到50區
間內。
Expression.between("age",new
Integer(13),new Integer(50));
表達式
Expression.in 對應SQL中的 ”field in …” 表達式
Expression.eqProperty 用于比較兩個屬性之間的值,對應SQL中的“field
= field”。
如:
Expression.eqProperty(
"TUser.groupID",
"TGroup.id"
);
Expression.gtProperty 用于比較兩個屬性之間的值,對應SQL中的“field
> field”。
Expression.geProperty 用于比較兩個屬性之間的值,對應SQL中的“field
>= field”。
Expression.ltProperty 用于比較兩個屬性之間的值,對應SQL中的“field
< field”。
Expression.leProperty 用于比較兩個屬性之間的值,對應SQL中的“field
<= field”。
Expression.and and關系組合。
如:
Expression.and(
Expression.eq("name","Erica"),
Expression.eq(
"sex",
new Integer(1)
)
);
Expression.or or關系組合。
如:
Hibernate Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
Expression.or(
Expression.eq("name","Erica"),
Expression.eq("name","Emma")
);
Expression.sql 作為補充,本方法提供了原生SQL語法的支持。我
們可以通過這個方法直接通過SQL語句限定查詢
條件。
下面的代碼返回所有名稱以“Erica”起始的記錄:
Expression.sql(
“lower({alias}.name) like lower(?)”,
"Erica%",
Hibernate.STRING
);
其中的“{alias}”將由Hibernate在運行期使
用當前關聯的POJO別名替換。
注意Expression 各方法中的屬性名參數(如Express.eq中的第一個參數),這里
所謂屬性名是POJO中對應實際庫表字段的屬性名(大小寫敏感),而非庫表中的實
際字段名稱。
Criteria 高級特性
限定返回的記錄范圍
通過criteria. setFirstResult/setMaxResults 方法可以限制一次查詢返回
的記錄范圍:
Criteria criteria = session.createCriteria(TUser.class);
//限定查詢返回檢索結果中,從第一百條結果開始的20條記錄
criteria.setFirstResult(100);
criteria.setMaxResults(20);
對查詢結果進行排序
//查詢所有groupId=2的記錄
//并分別按照姓名(順序)和groupId(逆序)排序
Criteria criteria = session.createCriteria(TUser.class);
criteria.add(Expression.eq("groupId",new Integer(2)));
criteria.addOrder(Order.asc("name"));
Hibernate Developer’s Guide Version 1.0
September 2, 2004 So many open source projects. Why not Open your Documents?
criteria.addOrder(Order.desc("groupId"));
Criteria作為一種對象化的查詢封裝模式,不過由于Hibernate在實現過程中將精力
更加集中在HQL查詢語言上,因此Criteria的功能實現還沒做到盡善盡美(這點上,OJB
的Criteria 實現倒是值得借鑒),因此,在實際開發中,建議還是采用Hibernate 官
方推薦的查詢封裝模式:HQL。