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实现数据的分组统计比较简单,这个操作作为技术点了解即可。