Hibernate的DetachedCriteria使用(含Criteria)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate的DetachedCriteria使用(含Criteria)相关的知识,希望对你有一定的参考价值。


Hibernate总的来说共有三种查询方式:HQL、QBC和SQL三种

HQL(Hibernate Query Language)

SQL(Structured Query Language)

QBC(Query By Criteria)

今天重点介绍QBC

这种方式比较面向对象方式,重点是有三个描述条件的对象:Restrictions,Order,Projections。使用QBC查询,一般需要以下三个步骤

  1. 使用Session实例的createCriteria()方法创建Criteria对象;
  2. 使用工具类Restrictions的方法为Criteria对象设置查询条件,Order工具类的方法设置排序方式,Projections工具类的方法进行统计和分组;
  3. 使用Criteria对象的list()方法进行查询并返回结果。

Restrictions、Order、Projections的常用方法

Restrictions类的常用方法(设置查询条件):

返回值类型

方法名称

描述

SimpleExpression

Restrictions.eq

等于(equal)

Criterion

Restrictions.allEq

使用Map,Key/Valu进行多个等于的比对

SimpleExpression

Restrictions.gt

大于(great than)

SimpleExpression

Restrictions.ge

大于等于(great than or equal)

SimpleExpression

Restrictions.lt

小于(less than)

SimpleExpression

Restrictions.le

小于等于(less than or equal)

Criterion

Restrictions.between

对应SQL的between

SimpleExpression

Restrictions.like

对应SQL的like

Criterion

Restrictions.in

对应SQL的in

LogicalExpression

Restrictions.and

and关系

LogicalExpression

Restrictions.or

or关系

Criterion

Restrictions.isNull

为空

Criterion

Restrictions.sqlRestriction

SQL限定查询

 

Order类的常用方法(设置排序方式):

返回值类型

方法名称

描述

Order

Order.asc

升序

Order

Order.desc

降序

 

Projections类的常用方法(统计和分组):

返回值类型

方法名称

描述

AggregateProjection

Projections.avg

求平均值

CountProjection

Projections.count

统计某属性的数量

CountProjection

Projections.countDistinct

统计某属性不同值的数量

PropertyProjection

Projections.groupProperty

指定某个属性为分组属性

AggregateProjection

Projections.max

求最大值

AggregateProjection

Projections.min

求最小值

ProjectionList

Projections.projectionList

创建一个ProjectionList对象

Projection

Projections.rowCount

查询结果集中的记录条数

AggregateProjection

Projections.sum

求某属性的合计

 

QBC的查询示例和基本理解

查询历史记录表中的供应商数据


private void getEQDetachedCriteria(Class<T> clasz)
Criteria criteria =getCurrentSession().createCriteria(VenAllHistory.class);
criteria.add(Restrictions.eq("PointerType","Vendor"));
criteria.addOrder(Order.desc("HistoryId"));
///分页查询前10条
criteria.setFirstResult(0);
criteria.setMaxResults(10);
criteria.list();

 

复合查询

复合查询就是在原有的查询基础上在进行查询,比如有Clazz班级,包含对象属性Student,那么我们希望查询 “包含学生姓名为Bob” 的班级,那么就可以使用复合查询:


Criteria criteria = session.createCriteria(Clazz.class);Criteria criteriaInner = criteria.createCriteria(Student.class);
criteriaInner.add(Restrictions.eq("name", "Bob"));
List clazzList = criteria.list();


DetachedCriteria、Criteria 使用区别

在常规的Web编程中,有大量的动态条件查询,即用户在网页上面自由选择某些条件,程序根据用户的选择条件,动态生成SQL语句,进行查询。
此时,我们不能在Web层使用Criteria,因为它是和Session绑定的。
DetachedCriteria可以解决这个问题,即在web层,程序员使用DetachedCriteria来构造查询条件,然后将这个 DetachedCriteria作为方法调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后,可以在session范围内直接构造Criteria,进行查询。就此,查询语句的构造完全被搬离到web层实现,而业务层则只负责完成持久化和查询的封装即可,与查询条件构造完全解耦,非常完美!

主要区别

父接口CriteriaSpecification,其下有子接口Criteria和实现类DetachedCriteria,Criteria和DetachedCriteria均可使用Criterion和Projection设置查询条件。可以设置FetchMode( 联合查询抓取的模式 ) ,设置排序方式。对于Criteria还可以设置FlushModel(冲刷 Session 的方式)和LockMode(数据库锁模式)。

Criteria和DetachedCriteria的主要区别在于创建的形式不一样,Criteria是在线的,所以它是由Hibernate Session进行创建的;而DetachedCriteria是离线的,创建时无需Session,它通过2个静态方法forClass(Class) 或 forEntityName(Name) 进行DetachedCriteria 的实例创建。

(另,Spring的框架提供了getHibernateTemplate ().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria来返回查询结果)

所以它也称为离线条件查询,即建立一个DetachedCriteria对象,将查询的条件等指定好,然后在session.beginTransaction()后将这个对象传入。通常这个对象可以在表示层建立,然后传入业务层进行查询。

 


private void getEQDetachedCriteria(Class<T> clasz)
DetachedCriteria criteria= DetachedCriteria.forClass(VenAllHistory.class);
criteria.add(Restrictions.eq("PointerType","Vendor"));
criteria.addOrder(Order.desc("HistoryId"));
Session session = this.getCurrentSession();
Criteria executableCriteria = criteria.getExecutableCriteria(session);
executableCriteria.setCacheable(true);
//return findByCriteria(criteria, -1, -1);
return executableCriteria.list();


DetachedCriteria作为子查询

//主查询:人员查询
DetachedCriteria searDc =
DetachedCriteria.forClass(QymlPerson.class);

//子查询:职务人员关系表
DetachedCriteria sub =
DetachedCriteria.forClass(QymlPositionUserLink.class);
sub.add(Restrictions.eq("positionunid", positionunid));
//子查询:指定查询的列(也就是select usernuid from ....)
sub.setProjection(Property.forName("userunid"));

//主查询和子查询关联(也就是where unid in (select userunid from...) )
searDc.add(Property.forName("unid").in(sub));

在上面的例子中,用个一个类似于下面SQL 的子查询

Select * from Person a where a.unid in (select userunid from PositionUserLink b where
b.positionunid = ..)

 

动态关联抓取

我们的抓取模式,对于1对多的关联的形式!是不是抓取过来呢?
你可以使用​​​setFetchMode()​​在运行时定义动态关联抓取的语义

List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.setFetchMode("mate", FetchMode.JOIN)
.setFetchMode("kittens", FetchMode.JOIN)
.list();

投影(Projections)、聚合(aggregation)和分组(grouping)

org.hibernate.criterion.​​Projections​​​是 ​​Projection​​​ 的实例工厂。 
我们通过调用setProjection()应用投影到一个查询。这个的意思就是查询哪一列的意思 
用来进行聚合操作,和sql中的聚合类似.求和/求平均值/统计记录数/…等等. 
还有用来获取获取对象的某些属性(表字段)或属性集合.正常情况下,查询返回的是对象或对象的集合.使用投影的话就可以只返回你需要的属性值.​​此时,即Hibernate不把记录封装对象了,只返回你在投影中设置的属性的值(值的集合)的数组​

List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount() )
//当你添加一个投影到一个投影列表中时 你可以为它指定一个别名:如
//.add( Projections.rowCount() ,"count")
.add( Projections.avg("weight") )
.add( Projections.max("weight") )
.add( Projections.groupProperty("color") )
)
.list();

可以选择把一个别名指派给一个投影,这样可以使投影值被约束或排序所引用。下面是两种不同的实现方式:

List results = session.createCriteria(Cat.class)
.setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
//.setProjection( Projections.groupProperty("color").as("colr") )
.addOrder( Order.asc("colr") )
.list();

也可以使用​​Property.forName()​​来表示投影:

List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount().as("catCountByColor") )
.add( Property.forName("name"))
.add( Property.forName("weight").avg().as("avgWeight") )
.add( Property.forName("weight").max().as("maxWeight") )
.add( Property.forName("color").group().as("color" )
)
.addOrder( Order.desc("catCountByColor") )
.addOrder( Order.desc("avgWeight") )
.list();

 

 

 

 

 

以上是关于Hibernate的DetachedCriteria使用(含Criteria)的主要内容,如果未能解决你的问题,请参考以下文章

hibernate.merge()方法怎么用

Hibernate→ 《Hibernate程序开发》教材大纲

(转)Hibernate框架基础——Hibernate API及Hibernate主配置文件

Hibernate之Hibernate环境配置

hibernate删除表的方法

Hibernate基础学习—Hibernate相关API介绍