1 Session查詢
Session接口裏面本身所定義的數據查詢只有一個根據ID查詢的操作方法,但是這個方法卻有兩個定義:
(1)根據主鍵查詢:public <T> T get(Class<T> entityType, Serializable id)
(2)根據主鍵查詢:public <T> T load(Class<T> theClass, Serializable id)
兩個操作方法上只差了一個單詞,那麼使用上有差別嗎?
範例:使用get()查詢
package org.lks.test;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class TestNewsGet {
public static void main(String[] args) {
News vo = HibernateSessionFactory.getSession().get(News.class, 100);
System.out.println(vo);
HibernateSessionFactory.closeSession();
}
}
Hibernate:
select
news0_.nid as nid1_0_0_,
news0_.ntitle as ntitle2_0_0_,
news0_.nvisits as nvisits3_0_0_,
news0_.nitem as nitem4_0_0_
from
hedb.news news0_
where
news0_.nid=?
null
package org.lks.test;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class TestNewsGet {
public static void main(String[] args) {
News vo = HibernateSessionFactory.getSession().load(News.class, 100);
System.out.println(vo);
HibernateSessionFactory.closeSession();
}
}
Hibernate:
select
news0_.nid as nid1_0_0_,
news0_.ntitle as ntitle2_0_0_,
news0_.nvisits as nvisits3_0_0_,
news0_.nitem as nitem4_0_0_
from
hedb.news news0_
where
news0_.nid=?
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [org.lks.pojo.News#100]
使用load()查詢的時候如果指定的ID不存在,那麼就會出現異常。
面試題:請問Hibernate中get()與load()方法有什麼區別?
(1)get()與load()方法都是在Session接口中定義的根據主鍵查詢的操作;
(2)get()方法查詢時,如果主鍵不存在,則返回null;
(3)load()方法查詢時,如果主鍵不存,則拋出異常。
2 Query查詢
面對數據操作中,數據的查詢部分永遠都是最爲複雜的部分,所以來講如果要進行更加合理的查詢操作,那麼必須依靠Query接口來實現,而如果要想取得此接口的實例化對象,必須依靠Session接口完成,在Session接口中定義有如下方法:
(1)取得Query接口對象:public Query createQuery(String queryString)
|————此處表示傳入一個hql語法進行數據查詢(Hibernate Query Language)
在Query接口裏面主要定義瞭如下幾個操作方法:
(1)設置要操作的數據:【Deprecated】default Query<R> setXxx(int position, 數據類型 val)
|————(since 5.2) use setParameter(int, Object) or setParameter(int, Object, Type) instead
Bind a positional float-valued parameter.
(2)設置參數:public Query<R> setParameter(int position, Object value)
;
(3)取得單個查詢結果:public R uniqueResult()
;
(4)查詢全部數據:public List<R> list()
;
(5)數據更新:public int executeUpdate()
;
2.1 數據查詢
在Hibernate裏面Session查詢不能夠勝任於複雜查詢,所以現在的所有查詢都通過Query接口完成,那麼在這個接口裏面要使用hql語言(極其類似於SQL語句)。
範例:查詢全部數據
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoA {
public static void main(String[] args) {
String hql = "FROM News AS n"; //hql查詢全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
List<News> all = query.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
}
}
現在通過以上的代碼可以發現如下幾點:
(1)在Hibernate裏面使用的都是HQL,但是在使用HQL的時候一定要注意,FROM子句之後跟的是POJO類的名字,必須注意大小寫News.java
(News),而AS
指的就是別名,一般情況下可以省略。
(2)在使用Hibernate進行數據查詢的時候,發現所有的內容都會自動以POJO類的形式返回,所有的實例化的操作部分都由Hibernate自動幫助用戶處理了;
所謂的HQL其語法的結構非常類似於SQL語法結構,那麼也可以編寫SELECT語句,但是大部分人不會這麼寫。
範例:查詢指定的數據列
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
public class QueryDemoA {
public static void main(String[] args) {
String hql = "SELECT n.ntitle,n.nitem FROM News AS n"; //hql查詢全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
List<Object[]> all = query.list();
Iterator<Object[]> iter = all.iterator();
while(iter.hasNext()){
Object[] obj = iter.next();
System.out.println(obj[0] + ", " + obj[1]);
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
此時的代碼的確是進行了數據列的操作限制,但是其結果發現爲了保證查詢,那麼返回的數據不再自動轉化爲News這個POJO類,而是以對象數組的形式返回,相比較自動匹配POJO類型,以上的操作明顯不方便。
Hibernate在設計的時候考慮到了以上的情況,所以在Hibernate裏面提供有一個專門負責轉換處理的類(org.hibernate.transform.AliasToBeanResultTransformer
),但是即便轉換了你也需要做一些輔助性的操作。隨後在Query接口裏面使用如下的轉換操作方法明確設置:
(1)設置結果轉換:【Deprecated】default Query<R> setParameters(Object[] values, Type[] types)
範例:手工轉換
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoC {
public static void main(String[] args) {
String hql = "SELECT n.ntitle AS ntitle,n.nitem AS nitem FROM News AS n"; //hql查詢全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setResultTransformer(new AliasToBeanResultTransformer(News.class));
List<News> all = query.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
在本代碼之中實際上只是一個功能的演示,如果真查詢,就查詢全部數據,千萬別做部分數據的查詢。
那麼既然可以實現查詢全部的操作,就一定可以實現根據ID查詢的操作,也就是說使用限定查詢。
範例:在Query中實現限定查詢
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoD {
public static void main(String[] args) {
String hql = "FROM News AS n WHERE n.nid=?"; //hql查詢全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
// query.setInteger(0, 3);
query.setParameter(0, 3); //所有的類型由Hibernate自己處理
News vo = (News) query.uniqueResult();
System.out.println(vo);
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
模糊查詢在Query中可以繼續像SQL那樣直接使用。
範例:實現模糊查詢
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoE {
public static void main(String[] args) {
String column = "ntitle";
String keyWord = "lks";
String hql = "FROM News AS n WHERE n." + column + " LIKE ?"; //hql查詢全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0, "%" + keyWord + "%");
List<News> all = query.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
各個數據庫之中最麻煩的在於分頁的支持不同,而Hibernate是一個跨數據庫的工具,所以裏面的分頁將使用統一的放式進行處理,在Query接口裏面定義有兩個操作方法:
(1)設置開始行:public Query<R> setFirstResult(int startPosition)
;
(2)設置最大返回行:Query<R> setMaxResults(int maxResult)
;
範例:數據分頁
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoF {
public static void main(String[] args) {
int currentPage = 2;
int lineSize = 3;
String column = "ntitle";
String keyWord = "";
String hql = "FROM News AS n WHERE n." + column + " LIKE ?"; //hql查詢全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0, "%" + keyWord + "%");
query.setFirstResult((currentPage - 1) * lineSize);
query.setMaxResults(lineSize);
List<News> all = query.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
不管是什麼數據庫,只要設置了分頁都會由Hibernate自己進行適應。
在Query接口裏面如果要進行數據統計的話,那麼就必須編寫SELECT語句了。但是統計的個數只有唯一的一個。
範例:統計數據個數
package org.lks.test;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
public class QueryDemoG {
public static void main(String[] args) {
String column = "ntitle";
String keyWord = "";
String hql = "SELECT COUNT(*) FROM News AS n WHERE n." + column + " LIKE ?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0, "%" + keyWord + "%");
System.out.println(query.uniqueResult());
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
Hibernate中返回的數據個數的統計結果類型爲Long。
編寫HQL的時候實際上也可以進行分組統計查詢。
範例:實現分組統計查詢
package org.lks.test;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
public class QueryDemoG {
public static void main(String[] args) {
String column = "ntitle";
String keyWord = "";
String hql = "SELECT n.nitem,COUNT(*) AS ncount,SUM(n.nvisits) AS nsum "
+ "FROM News AS n WHERE n." + column
+ " LIKE ? GROUP BY n.nitem HAVING SUM(n.nvisits)>50";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setParameter(0, "%" + keyWord + "%");
List<Object[]> all = query.list();
Iterator<Object[]> iter = all.iterator();
while(iter.hasNext()){
System.out.println(Arrays.toString(iter.next()));
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
如果需要在Query查詢之中爲查詢列設置別名的話,一定要加上AS
,否則無效。
2.2 使用SQL查詢(不建議使用)
即使HQL的語法很像SQL語法,但是它依然不是SQL,所以很多時候可能支持度有限。所以爲了解決這樣的問題,在Hibernate裏面也可以使用普通的SQL語句進行數據的查詢,但是如果要想將查詢結果變爲POJO類的形式,則必須使用轉換操作。
如果要創建SQL查詢,在Session接口裏面定義有如下方法:
(1)創建SQL查詢:public NativeQuery createSQLQuery(String queryString)
;
範例:使用SQL查詢
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoI {
public static void main(String[] args) {
String hql = "SELECT ntitle,nitem FROM news";
Query query = HibernateSessionFactory.getSession().createSQLQuery(hql);
query.setResultTransformer(new AliasToBeanResultTransformer(News.class));
List<News> all = query.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
既然都已經擺脫了PreparedStatement接口了,那麼這樣的操作不寫也罷。
2.3 查詢佔位符
在之前編寫的時候使用的HQL的佔位符都是?
(推薦做法),但是在HQL裏面對於佔位符還有另外一種形式使用:名稱
描述,這樣的目的主要是爲了解決設置的內容過多的時候,?
容易數不清楚。
範例:使用其它佔位符
package org.lks.test;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoJ {
public static void main(String[] args) {
String hql = "FROM News AS n WHERE n.nid=:pnid"; //hql查詢全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
// query.setInteger(0, 3);
query.setParameter("pnid", 3); //所有的類型由Hibernate自己處理
News vo = (News) query.uniqueResult();
System.out.println(vo);
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
那麼此時有人提出來了,能不能?
和佔位符一起使用呢?如果要混合使用,那麼請將?
寫在:
之前。
範例:混合使用
package org.lks.test;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoJ {
public static void main(String[] args) {
String hql = "FROM News AS n WHERE n.nitem=? AND n.nid=:pnid"; //hql查詢全部
Query query = HibernateSessionFactory.getSession().createQuery(hql);
// query.setInteger(0, 3);
query.setParameter(0, "笨蛋");
query.setParameter("pnid", 3); //所有的類型由Hibernate自己處理
News vo = (News) query.uniqueResult();
System.out.println(vo);
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
雖然支持:
的佔位符,但是正常人都使用?
完成。
2.4 在配置文件中編寫HQL(不推薦)
有些人認爲對於HQL操作如果直接寫在程序之中可能會比較混亂,希望可以將HQL和查詢分開,如果要想不分開那麼必須藉助於*.hbm.xml
文件完成。
範例:在News.hbm.xml文件裏面增加如下的查詢配置(在根節點之下編寫)
<query name="findById">
FROM News AS n WHERE n.nid=?
</query>
那麼自然要在程序之中讀取這樣的配置信息。
範例:讀取配置的查詢信息
package org.lks.test;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class QueryDemoL {
public static void main(String[] args) {
//讀取配置文件中的findByID配置的元素內容
Query query = HibernateSessionFactory.getSession().getNamedQuery("findById");
query.setParameter(0, 3); //所有的類型由Hibernate自己處理
News vo = (News) query.uniqueResult();
System.out.println(vo);
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
這些只是Hibernate發展初期的時候,所遺留的一些功能,但是沒有實用性。
2.5 更新操作
在Hibernate最早設計的時候,所有的更新操作只能夠通過update()
方法或者是delete()
執行,但是隨着時間的發展,發現一個問題,如果使用這些方法無法實現部分數據的更新。
從Hibernate 2.x開始針對於Query接口實現了功能的擴充,讓其可以實現數據更新操作。
範例:使用Query接口更新數據
package org.lks.test;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
public class QueryUpdateA {
public static void main(String[] args) {
String hql = "UPDATE News SET ntitle=?,nvisits=? WHERE nid=?";
Query query = HibernateSessionFactory.getSession().createSQLQuery(hql);
query.setParameter(0, "play backetball");
query.setParameter(1, 20000);
query.setParameter(2, 5);
int len = query.executeUpdate();
System.out.println(len);
HibernateSessionFactory.getSession().beginTransaction().commit();
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
範例:實現數據刪除操作
package org.lks.test;
import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
public class QueryDelete {
public static void main(String[] args) {
String hql = "DELETE FROM News WHERE nid=?";
Query query = HibernateSessionFactory.getSession().createSQLQuery(hql);
query.setParameter(0, 1);
int len = query.executeUpdate();
System.out.println(len);
HibernateSessionFactory.getSession().beginTransaction().commit();
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
雖然此處實現了更新操作,但是在Query接口上設計有些不妥,不過這個不妥也都成爲習慣了。
3 Criteria接口
大部分情況下如果要使用查詢操作,首選的一定是HQL查詢,但是在Hibernate之中有一個特殊情況,:Hibernate屬於ORMapping的映射框架,那麼如果是ORMapping的映射框架,所有的操作都應該以對象爲主進行使用,那麼Query的使用就不符合於這種要求了,所以在查詢的基礎上又擴充了一個基於對象模式的查詢接口:Criteria接口,而這個接口的創建依靠Session接口:【Deprecated】public Criteria createCriteria(Class persistentClass)
。
範例:查詢全部數據
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class CriteriaDemoA {
public static void main(String[] args) {
Criteria criteria = HibernateSessionFactory.getSession().createCriteria(News.class);
List<News> all = criteria.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
News vo = iter.next();
System.out.println(vo);
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
如果只是這種簡單的查詢,那麼使用Criteria接口一定要比使用Query接口更加的容易。
但實際的開發之中,雖然需要查詢全部,但是很多時候都會需要限定查詢,所以在Criteria裏面也支持查詢條件的設置,此接口定義瞭如下一個增加查詢條件的方法:public Criteria add(Criterion criterion)
。
那麼這個時候對於所有的條件的創建還需要使用另外一個類:org.hibernate.criterion.Restrictions
,這個類定義瞭如下幾個操作的方法:
(1)邏輯運算:
|——與運算(AND):public static Conjunction and(Criterion... predicates)
|——或運算(OR):public static Disjunction or(Criterion... predicates)
|——非運算(NOT):public static Criterion not(Criterion expression)
(2)關係運算:
|——==
:public static SimpleExpression eq(String propertyName, Object value)
|——!=
:public static SimpleExpression ne(String propertyName, Object value)
|——>
:public static SimpleExpression gt(String propertyName, Object value)
|——>=
:public static SimpleExpression ge(String propertyName, Object value)
|——<
:public static SimpleExpression lt(String propertyName, Object value)
|——<=
:public static SimpleExpression le(String propertyName, Object value)
|——LIKE
:public static SimpleExpression like(String propertyName, Object value)
|——IN
:public static Criterion in(String propertyName, Collection values)
|——BETWEEN..AND..
:public static Criterion between(String propertyName, Object low, Object high)
|——ISNULL
:public static Criterion isNull(String propertyName)
|——ISNOTNULL
:public static Criterion isNotNull(String propertyName)
範例:根據ID查詢
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class CriteriaDemoB {
public static void main(String[] args) {
Criteria criteria = HibernateSessionFactory.getSession().createCriteria(News.class);
criteria.add(Restrictions.eq("nid", 3));
List<News> all = criteria.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
News vo = iter.next();
System.out.println(vo);
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
範例:取得訪問量大於100的信息
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class CriteriaDemoC {
public static void main(String[] args) {
Criteria criteria = HibernateSessionFactory.getSession().createCriteria(News.class);
criteria.add(Restrictions.gt("nvisits", 100));
List<News> all = criteria.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
News vo = iter.next();
System.out.println(vo);
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
在整個Criteria操作之中,如果要說最有用處的操作只有一個:IN()操作,因爲這個接口的IN操作可以直接將要查詢的數據以Collection形式保存。
範例:使用IN查詢
package org.lks.test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class CriteriaDemoD {
public static void main(String[] args) {
Set<Integer> ids = new HashSet<Integer>();
ids.add(4);
ids.add(6);
ids.add(7);
Criteria criteria = HibernateSessionFactory.getSession().createCriteria(News.class);
criteria.add(Restrictions.in("nid", ids));
List<News> all = criteria.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
News vo = iter.next();
System.out.println(vo);
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
範例:模糊查詢
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class CriteriaDemoD {
public static void main(String[] args) {
Criteria criteria = HibernateSessionFactory.getSession().createCriteria(News.class);
criteria.add(Restrictions.like("ntitle", "%%"));
List<News> all = criteria.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
News vo = iter.next();
System.out.println(vo);
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
使用以上方法進行模糊查詢需要注意模糊查詢列要爲字符串類型,否則與使用等號無區別。
範例:設置多個條件(and()
、or()
)
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class CriteriaDemoD {
public static void main(String[] args) {
Criteria criteria = HibernateSessionFactory.getSession().createCriteria(News.class);
criteria.add(Restrictions.and(Restrictions.gt("nvisits", 2000), Restrictions.eq("nitem", "笨蛋")));
List<News> all = criteria.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
News vo = iter.next();
System.out.println(vo);
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
在使用Criteria接口操作的時候還可以設置排序,裏面提供了排序的方式:public Criteria addOrder(Order order)
(1)升序排列:public static Order asc(String propertyName)
(2)降序排列:public static Order desc(String propertyName)
範例:排序
package org.lks.test;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class CriteriaDemoD {
public static void main(String[] args) {
Criteria criteria = HibernateSessionFactory.getSession().createCriteria(News.class);
criteria.addOrder(Order.desc("nid"));
List<News> all = criteria.list();
Iterator<News> iter = all.iterator();
while(iter.hasNext()){
News vo = iter.next();
System.out.println(vo);
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
在Criteria接口裏面也支持分組統計查詢,但是這個查詢需要使用此方法支持:
(1)分組統計操作:public Criteria setProjection(Projection projection)
如果要設置條件則應該使用org.hibernate.criterion.Projections
實現統計,有如下的方法:
(1)COUNT(*)
:public static Projection rowCount()
(2)COUNT(字段)
:public static CountProjection count(String propertyName)
(3)COUNT(DISTINCT 字段):public static CountProjection countDistinct(String propertyName)
(4)AVG()
:public static AggregateProjection avg(String propertyName)
(5)SUM()
:public static AggregateProjection sum(String propertyName)
(6)MAX()
:public static AggregateProjection max(String propertyName)
(7)MIN()
:public static AggregateProjection min(String propertyName)
(8)設置分組字段:public static PropertyProjection groupProperty(String propertyName)
這些操作都應該是一起查詢出來的,這個時候還需要另外一個類的支持:org.hibernate.criterion.ProjectionList
(1)取得PeojectionList:public static ProjectionList projectionList()
而取得了ProjectionList之後就可以繼續增加多個條件了:public ProjectionList add(Projection projection)
範例:實現信息統計
package org.lks.test;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;
public class CriteriaDemoD {
public static void main(String[] args) {
Criteria criteria = HibernateSessionFactory.getSession().createCriteria(News.class);
ProjectionList list = Projections.projectionList();
list.add(Projections.rowCount());
list.add(Projections.avg("nvisits"));
list.add(Projections.groupProperty("ntitle"));
list.add(Projections.max("nid"));
criteria.setProjection(list);
List<Object[]> all = criteria.list();
Iterator<Object[]> iter = all.iterator();
while(iter.hasNext()){
System.out.println(Arrays.toString(iter.next()));
}
HibernateSessionFactory.closeSession();
System.exit(0);
}
}
還是使用Query+HQL實現數據的分組統計比較簡單,這個操作作爲技術點了解即可。