hibernate 动态查询 Criteria
来源: Javaeye
分类: Java
发表: 243天前 (2008-04-16 11:19:17.39)
阅读: 206 次
要對資料庫管理系統進行操作,最基本的就是使用SQL(Standard Query Language)語句,大部份的資料庫都支援標準的SQL語句,然而也有一些特定於資料庫的SQL語句,應用程式配合SQL語句進行資料庫查詢時,若使用到特定於資料庫的SQL語句,程式本身會有相依於特定資料庫的問題。
使用Hibernate時,即使您不了解SQL的使用與撰寫,也可以使用它所提供的API來進行SQL語句查詢,org.hibernate.Criteria對SQL進行封裝,您可以從Java物件的觀點來組合各種查詢條件,由Hibernate自動為您產生SQL語句,而不用特別管理SQL與資料庫相依的問題。
以最基本的查詢來說,如果您想要查詢某個物件所對應的資料表中所有的內容,您可以如下進行查詢:
Criteria criteria = session.createCriteria(User.class);
List users = criteria.list();
for(Iterator it = users.iterator(); it.hasNext(); ) {
User user = (User) it.next();
System.out.println(user.getId() +
" \t " + user.getName() +
"/" + user.getAge());
}
Criteria建立後,若不給予任何的條件,預設是查詢物件所對應表格之所有資料,如果您執行以上的程式片段,並於設定檔中設定了了Hibernate的”show_sql”屬性,則可以在主控下看到以下的SQL語句之產生:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_
Criteria基本查詢條件設定
org.hibernate.Criteria實際上是個條件附加的容器,如果想要設定查詢條件,則要使用org.hibernate.criterion.Restrictions的各種靜態方法傳回org.hibernate.criterion.Criteria實例,傳回的每個org.hibernate.criterion.Criteria實例代表著一個條件,您要使用org.hibernate.Criteria的add()方法加入這些條件實例,例如查詢”age”大於20且小於40的資料:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.gt("age", new Integer(20)));
criteria.add(Restrictions.lt("age", new Integer(40)));
List users = criteria.list();
for(Iterator it = users.iterator(); it.hasNext(); ) {
User user = (User) it.next();
System.out.println(user.getId() +
" \t " + user.getName() +
"/" + user.getAge());
}
Restrictions的gt()方法表示大於(great than)的條件,而lt表示小於(less than)的條件,執行以上程式片段,觀察所產生的SQL語句,將使用where與and子句產來完成SQL的條件查詢:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.age>? and this_.age
使用add()方法加入條件時,預設是使用and來組合條件,如果要用or的方式來組合條件,則可以使用Restrictions.or()方法,例如結合age等於(eq)20或(or)age為空(isNull)的條件:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.or(
Restrictions.eq("age", new Integer(20)),
Restrictions.isNull("age")
));
List users = criteria.list();
觀察所產生的SQL語句,將使用where與or子句完成SQL的條件查詢:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where (this_.age=? or this_.age is null)
您也可以使用Restrictions.like()方法來進行SQL中like子句的功能,例如查詢”name”中名稱為”just”開頭的資料:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.like("name", "just%"));
List users = criteria.list();
觀察所產生的SQL語句如下:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.name like ?
Restrictions的幾個常用限定查詢方法如下表所示:
方法 說明
Restrictions.eq 等於
Restrictions.allEq 使用Map,使用key/value進行多個等於的比對
Restrictions.gt 大於 >
Restrictions.ge 大於等於 >=
Restrictions.lt 小於 <
Restrictions.le 小於等於 <=
Restrictions.between 對應SQL的BETWEEN子句
Restrictions.like 對應SQL的LIKE子句
Restrictions.in 對應SQL的in子句
Restrictions.and and關係
Restrictions.or or關係
Criteria進階查詢條件設定
使用Criteria進行查詢時,不僅僅能組合出SQL中where子句的功能,還可以組合出如排序、統計、分組等的查詢功能。
排序
您可以使用Criteria進行查詢,並使用org.hibernate.criterion.Order對結果進行排序,例如使用Oder.asc(),指定根據”age”由小到大排序(反之則使用desc()):
Criteria criteria = session.createCriteria(User.class);
criteria.addOrder(Order.asc("age"));
List users = criteria.list();
注意在加入Order條件時,使用的是addOrder()方法,而不是add()方法,在產生SQL語句時,會使用order by與asc(desc)來進行排序指定:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ order by this_.age asc
限定查詢筆數
Criteria的setMaxResults()方法可以限定查詢回來的筆數,如果配合setFirstResult()設定傳回查詢結果第一筆資料的位置,就可以實現簡單的分頁,例如傳回第51筆之後的50筆資料(如果有的話):
Criteria criteria = session.createCriteria(User.class);
criteria.setFirstResult(51);
criteria.setMaxResults(50);
List users = criteria.list();
根據您所指定得資料庫,Hibernate將自動產生與資料庫相依的限定筆數查詢子句,例如在MySQL中,將使用limit產生以下的SQL語句:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ limit ?, ?
統計動作
您可以對查詢結果進行統計動作,使用org.hibernate.criterion.Projections的avg()、rowCount()、count()、max()、min()、 countDistinct()等方法,再搭配Criteria的setProjection()方法加入條件設定,例如對查詢結果的"age"作平均:
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(Projections.avg("age"));
List users = criteria.list();
上面的程式將由Hibernate自動產生SQL的avg函數進行平均計算:
Hibernate: select avg(this_.age) as y0_ from T_USER this_
分組
還可以配合Projections的groupProperty()來對結果進行分組,例如以"age"進行分組,也就是如果資料中"age"如果有 20、20、25、30,則以下會顯示20、25、30:
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(Projections.groupProperty("age"));
List users = criteria.list();
上面的程式將由Hibernate自動產生SQL的group by子句進行分組計算:
Hibernate: select this_.age as y0_ from T_USER this_ group by this_.age
如果想同時結合統計與分組功能,則可以使用org.hibernate.criterion.ProjectionList,例如下面的程式會計算每個年齡各有多少個人:
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.groupProperty("age"));
projectionList.add(Projections.rowCount());
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(projectionList);
List users = criteria.list();
觀察所產生的SQL語句,將使用group by先進行分組,再針對每個分組進行count函數的計數
Hibernate: select this_.age as y0_, count(*) as y1_ from T_USER this_ group by this_.age
根據已知物件進行查詢
設定查詢條件並非一定要使用Restrictions,如果屬性條件很多,使用Restrictions也不方便,如果有一個已知的物件,則可以根據這個物件作為查詢的依據,看看是否有屬性與之類似的物件,例如:
User user = new User();
user.setAge(new Integer(30));
Criteria criteria = session.createCriteria(User.class);
criteria.add(Example.create(user));
List users = criteria.list();
您可以透過org.hibernate.criterion.Example的create()方法來建立Example實例,Example實作了Criteria介面,因此可以使用add()方法加入至Criteria條件設定之中,Hibernate將自動過濾掉空屬性,根據已知物件上已設定的屬性,判定是否產生於where子句之中:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where (this_.age=?)
設定SQL範本
如果您了解如何撰寫SQL語句,想要設定一些Hibernate產生SQL時的範本,您也可以使用Restrictions的sqlRestriction()方法,提供SQL語法範本作限定查詢,例如查詢name以cater開頭的資料:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.sqlRestriction("{alias}.name LIKE (?)", "cater%", Hibernate.STRING));
List users = criteria.list();
其中alias將被替換為與User類別相關的名稱,而?將被替換為cater%,也就是第二個參數所提供的值,sqlRestriction()方法第一個參數所設定的是where子句的部份,所以在SQL撰寫時,不必再寫where,觀察所產生的SQL語句,將使用您所設定的SQL範本作為基礎,來完成SQL的條件查詢:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.name LIKE (?)
如果有多個查詢條件,例如between子句的查詢,則可以如下:
Criteria criteria = session.createCriteria(User.class);
Integer[] ages = {new Integer(20), new Integer(40)};
Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};
criteria.add(Restrictions.sqlRestriction("{alias}.age BETWEEN (?) AND (?)", ages, types));
List users = criteria.list();
觀察所產生的SQL語句如下:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.age BETWEEN (?) AND (?)
使用DetchedCriteria
Criteria與Session綁定,其生命週期跟隨著Session結束而結束,使用Criteria時進行查詢時,每次都要於執行時期動態建立物件,並加入各種查詢條件,隨著Session的回收,Criteria也跟著回收。
為了能夠重複使用Criteria物件,在Hibernate 3中新增了org.hibernate.criterion.DetchedCriteria,您可以先建立DetchedCriteria實例,並加入各種查詢條件,並於需要查詢時再與Session綁定,獲得一個綁定Session的Criteria物件,例如:
// 先建立DetchedCriteria物件
DetachedCriteria detchedCriteria = DetachedCriteria.forClass(User.class);
// 加入查詢條件
detchedCriteria.add(Restrictions.ge("age",new Integer(25)));
Session session = sessionFactory.openSession();
// 綁定Session並返回一個Criteria實例
Criteria criteria = detchedCriteria.getExecutableCriteria(session);
List users = criteria.list();
結論
Hibernate的Criteria API可以讓您使用物件的方式,組合出查詢資料庫系統的條件,Hibernate會自動依您所使用的資料庫,動態產生SQL語句,讓您的應用程式在存取資料庫時,不致於因撰寫了特定的SQL而相依於特定的資料庫,如果您的開發人員不熟悉SQL語句的撰寫,也可以試著使用Criteria來解決查詢資料庫的需求。
分享到:
相关推荐
Hibernate条件查询Criteria.docHibernate条件查询Criteria.doc
### Hibernate Criteria 查询详解 #### 一、概述 Hibernate Criteria 查询是一种强大的对象化查询方式,它为开发者提供了一种灵活而直观的方式来构建复杂的查询逻辑。与传统的SQL查询相比,Criteria查询更加面向...
在Hibernate中,我们通常使用HQL(Hibernate Query Language)或Criteria API进行查询,但这些方式并不支持复杂的动态查询。为了实现动态SQL,我们可以借助于Hibernate的QBC(Query By Criteria)和Criteria API,...
这个案例是根据分组查询,并且得到每组的条数,不懂得可以q我:1710086675,欢迎认识更多新朋友
Hibernate条件查询Criteria[参考].pdf
Hibernate中的Criteria API是一种用于执行动态查询的机制,它允许开发者在运行时构建SQL查询,而无需直接编写SQL语句。Criteria API提供了更加面向对象的方式来处理数据库查询,这使得代码更易于理解和维护,尤其是...
Criteria API基于面向对象的方式进行查询构建,可以动态地添加各种查询条件,包括等值比较、范围查询、模糊查询等,使得查询操作更加直观和易于管理。 ### 模糊查询的意义 模糊查询是数据库操作中常见的一种需求,...
在Java持久层框架Hibernate中,Criteria API是一种动态构建SQL查询的方法,它允许开发者在运行时构建查询,提供了更面向对象的查询方式。本篇将详细阐述Hibernate Criteria API的使用。 首先,Criteria API由...
### Hibernate-Criteria 模糊查询详解 在Java的持久化技术中,Hibernate作为ORM(对象关系映射)框架的一种,提供了强大的数据访问能力。而其中的`Criteria`接口更是为复杂的查询需求提供了一种灵活且功能强大的...
在Java的持久化框架Hibernate中,Criteria API是一种用于构建动态查询的强大工具,它允许开发者以对象化的方式构建SQL语句,而无需直接编写SQL代码。本篇将详细讲解如何在Hibernate中利用Criteria查询来实现类似SQL...
Criteria API是Hibernate提供的一个高级查询接口,它允许开发者在运行时构建动态查询。Criteria查询是基于对象的,通过调用一系列方法来设置查询条件,这些条件在查询执行时被转化为对应的SQL语句。 2. **Criteria...
开发者可以通过字符串拼接动态生成HQL语句,实现动态查询。 2.3 Criteria与HQL结合 在复杂场景下,可以将Criteria与HQL结合,以达到更灵活的查询效果。例如,使用Criteria构造基本查询,然后用HQL处理更复杂的部分...
Hibernate 的 Criteria 是一个完全面向对象、可扩展的条件查询 API,通过它完全不需要考虑数据库底层如何实现、SQL 语句如何实现。Criteria 提供了灵活的查询条件组装方式,能够满足开发中复杂的查询需求。 一、...
使用Hibernate時,即使您不了解SQL的使用與撰寫,也可以使用它所提供的API來進行SQL語句查詢,org.hibernate.Criteria對SQL進行封裝,您可以從Java物件的觀點來組合各種查詢條件,由Hibernate自動為您產生SQL語句,...
### Hibernate Criteria 分组、排序与关联查询详解 #### 标题与描述理解 - **标题**:“hibernate criteria 分组 排序 关联”这一标题明确了本文将围绕Hibernate Criteria API进行分组、排序以及关联查询的具体...
通过上述介绍,我们可以看到,Hibernate的Criteria API提供了一个强大且灵活的数据查询解决方案,它不仅支持基本的查询需求,还能处理复杂的查询场景,如排序、分页、聚合函数、分组统计以及条件过滤等。这使得开发...
在实际开发中,Hibernate Criteria查询提供了很大的便利性,尤其是在处理动态查询和复杂查询时。通过熟练掌握Criteria API,可以编写出更简洁、更易于维护的代码。希望这份资料能帮助你更好地理解和运用Hibernate的...
- **Criteria API**:是Hibernate提供的一种灵活且强大的查询方式,允许开发者通过程序化的方式来构建查询条件。 - **Order**:用于表示排序规则的对象,包含升序(asc)和降序(desc)两种类型。 - **Criteria....