第6章深入使用Hibernate 6.5 条件查询

来源:互联网 发布:服装设计软件下载 编辑:程序博客网 时间:2024/06/06 04:34

6.5 条件查询

条件查询是更具面向对象特色的数据查询方式。条件查询通过如下三个类完成:

*Criteria:代表一次查询

*Criterion:代表一个查询条件

*Restrictions:产生查询条件的工具类

执行条件查询的步骤如下:

1)获得Hibernate的Session对象

2)以Session对象创建Criteria对象。

3)使用Restrictions的静态方法创建Criterion查询条件

4)向Criteria查询中添加Criterion查询条件

5)执行Criteria的list()或uniqueResult()方法返回结果集

示例程序:

<span style="font-size:18px;">//使用createCriteria开始条件查询List l = session.createCriteria(Student.class)//根据Student的属性进行过滤数据.add( Restrictions.gt("name" , "a")).list();</span>

<span style="font-size:18px;">List l = session.createCriteria(Student.class)//此处增加限制条件必须是Student已经存在的属性.add( Restrictions.gt("studentNumber" , 20050231L))//如果要增加对Student的关联类的属性的限制//则必须重新createCriteria()//如果此关联属性是集合,则只要集合里任意一个对象的属性满足下面条件即可//.createCriteria("enrolments")//.add( Restrictions.gt("semester" , 2)).createAlias("enrolments", "en").add( Restrictions.gt("en.semester" , 2)).list();</span>

Criteria对象并不具备任何数据筛选功能,但程序可以通过向Criteria对象中组合多个Criteriation(每个Criteriation对象代表一个过滤条件)即可实现数据过滤了。

Criteria包含如下两个方法,用于完成查询分页。

*Criteria setFirstResult(int firstResult):设置查询返回的第一行记录。

*Criteria setMaxResults(int maxResults):设置查询返回的记录数。

还包含如下常用方法:

*Criteria add(Criteriation criterion):增加查询条件

*Criteria addOrder(Order order):增加排序规则

*List list():返回结果集

Criteriation接口代表一个查询条件,该查询条件有Restrictions负责产生。Restrictions是专门用于产生查询条件的工具类,它的方法大部分都是静态方法,常有的方法如下:

*static Criteriation allEq(Map propertyNameValues):判断指定属性(有Map参数的key指定)和指定值(由Map参数的value指定)是否完全相等。

*statci Criteration between(String propertyName,Object lo,Object hi):判断属性值在某个范围之内

*static Criteration ilike(String propertyName,Object value):判断属性值匹配某个字符串

*static Criteration ilike(String propertyName,String value,MatchMode matchMode):判断属性值匹配某个字符串,并确定匹配模式

*static Criteration in(String propertyName,Collection values):判断属性值在某个集合内。

*static Criteration in(String popertyName,Object[] values):判断属性值是数组元素的其中之一。

*static Criteration isEmpty(String propertyName):

*static Criteration isNotEmpty(String propertyName):

*static Criteration isNull(String propertyName):

*static Criteration isNotNull(String propertyName):

*static Criteration not(Criteration expression):对Criteraion求否

*static Criteration sezeEq(String propertyName,int size):判断某个属性的元素个数是否与size相等

*static Criteration sqlRestriction(String sql):直接使用sql语句作为筛选条件

*static Criteration sqlRestriction(String sql,Object[] values,Type[] types):直接使用带参数占位符的SQL语句作为条件,并指定多个参数值。

*static Criteration sqlRestriction(String sql,Object value,Type type):直接使用带参数占位符的SQL语句作为条件,并指定参数值。

Order实例代表一个排序标准,Order有如下标准方法。

*static Order asc(String propertyName):

*static Order desc(String propertyName):

6.5.1 关联和动态关联

如果需要使用关联实体的属性来增加查询条件,则应该对属性再次使用createCriteria方法。

<span style="font-size:18px;"><span style="font-size: 18px;">List l = session.createCriteria(Student.class).add( Restrictions.gt("studentNumber" , 20050231L)).createCriteria("enrolments").add( Restrictions.gt("semester" , 2)).list();</span></span>

还可使用条件查询的替换形态:

<span style="font-size:18px;"><span style="font-size: 18px;">List l = session.createCriteria(Student.class).add( Restrictions.gt("studentNumber" , 20050231L)).createAlias("enrolments", "en").add( Restrictions.gt("en.semester" , 2)).list();</span></span>
createAlias()方法并不创建一个新的Criteria实例,它只是给关联实体(包含集合里包含的关键实体)起一个别名,让后面的过滤条件可根据该关联实体进行筛选。

如果希望在条件查询中改变延迟加载策略(就像在HQL查询中使用fetch关键字一样),就可调用createCriteria()或craeteAlias()方法建立关联时指定FetchMode参数来控制。也可通过Criteria的setFetchMode()方法来实现,该方法也接受一个FetchMode参数。

Fetch里有如下几个常量:

*DEFAULT:使用配置文件指定的延迟加载策略处理。

*JSON:使用外连接,预初始化所有关联实体。

*SELECT:启用延迟加载,系统将使用单独的select语句来初始化关联实体。只有当真正访问关联实体的时候,才会执行第二条select语句。

6.5.2 投影、聚合和分组

投影运算实际上就是一种基于列的运算,通常用于投影到指定列,还可以完成SQL语句中常用的分组、组筛选等功能。

Hibernate的条件过滤中使用Projection代表投影运算,Projection是一个接口,而Projections作为Projection的工厂,负责生成Projection对象。

通过Criteria提供的setProjection(Projection projection)方法来进行投影运算。

Hibernate提供了一个ProjectionList类,该类是Projection的子类。

一个条件查询的投影运算通常有如下程序结构:

List cats = session.createCriteria(Cat.class)

.addProjection(Projections.projectionList()

.add(Projections.rowCount())

.add(Projections.avg("weight"))

.add(Projections.max("weight"))

.add(Projections.min("weight"))

.add(Projections.groupProperty("color")) )

.addOrder(Order.asc("color"))

.list();

在Projections工具类中提供了如下几个静态方法:

*AggregateProjection avg(String propertyName):计算特定属性的平均值。类似于avg函数

*CountProjection count(String propertyName):统计查询结果在某列上的记录条数。

*CountProjection countDistinct(String propertyName):

*PropertyProjection groupProperty(String propertyName):

*AggregateProjection max(String propertyName):

*AggregateProjection min(String propertyName):

*Projection rowCount():

*AggregateProjection sum(String propertyName):

*使用Projections的alias()方法为指定投影指定别名

//

.add(Projections.alias(Projections.rowCount(),"c"))

//

*使用SimpleProjection的as()方法为自身指定别名

//

.add(Projections.groupProperty("course").as("c"))

//

*使用ProjectionList的add()方法添加投影时指定别名

//

.add(Projections.groupProperty("course"),"c")

.add(Projections.rowCount(),"rc")

//

除此之外,Hibernate还提供了Property执行投影运算:

//使用Property只选出指定列

List l = session.createCriteria(Student.class)

.setProjection(Property.forName("name"))

.list();

使用Property还可根据指定列来过滤记录:

//使用Property选出指定列,并根据指定列过滤数据

List l = session.createCriteria(Enrolment.class)

.createAlias("student","s")

.setProjection(Projections.projectionList()

.add(Property.forName("courese))

.add(Property.forName("s.name")))

.add(Property.forName("s.name").eq("孙悟空"))

.list();

6.5.3 离线查询和子查询

条件查询的离线查询由DetachedCriteria来代表,DetachedCriteria类允许在一个Session范围之外创建一个查询,并且可以使用任意Session来执行它。

//创建指定持久化类的离线查询

 DetachedCriteria.forClass(Class po)

除此之外,DetachedCriteria还可代表子查询,当我们把DetachedCriteria传入Criteria中作为查询条件时,DetachedCriteria就变成了子查询。条件实例包含子查询通过Subqueries或者Property来获得。

//执行离线查询private void datached(){//定义一个离线查询DetachedCriteria query = DetachedCriteria.forClass(Student.class).setProjection(Property.forName("name"));//打开Session和事务Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();//执行离线查询List l = query.getExecutableCriteria(session).list();//遍历查询的结果for (Iterator it = l.iterator();it.hasNext() ; ){System.out.println(it.next());}tx.commit();HibernateUtil.closeSession();}//执行子查询private void subQuery(){//定义一个离线查询DetachedCriteria subQuery = DetachedCriteria.forClass(Student.class).setProjection(Property.forName("name"));//打开Session和事务Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();//执行子查询List l = session.createCriteria(Student.class).add( Property.forName("name").in(subQuery)).list();//遍历查询的结果for (Iterator it = l.iterator();it.hasNext() ; ){System.out.println(it.next());}tx.commit();HibernateUtil.closeSession();}

0 0
原创粉丝点击