hibernate—QBC

QBC查询就是通过使用Hibernate提供的Query By Criteria API来查询对象,这种API封装了SQL语句的动态拼装,对查询提供了更加面向对象的功能接口。我们看下面的示例程序:

Criteria criteria=session.createCriteria(User.class);   criteria.add(Expression.eq(“name”,”zx”));   criteria.add(Expression.eq(“age”,new Integer(27));   List list=criteria.list();

当执行criteria.list()时会生成类似这样的SQL语句:

Select * from user where name=’zx’   and   age=27;

所以在这里我们可以看出,Criteria实际上是一个查询容器,它对查询条件表达式的添加进行了封装,具体的查询条件是通过add()方法添加 的,而且具体的查询条件的表达式运算是通过Expression指定的。Hibernate在运行期会根据Criteria指定的表达式条件来添加查询条 件,并且生成查询语句。这种方式非常符合Java以及所有面向对象编程语言的编程方式,所以大多数的持久层框架都提供了对这种方式查询的支持。下面我们讲 解这种查询方式的各个技术细节。

1、Criteria查询表达式:

正如我们所见,Expression对查询语句的表达式进行了封装和限制,下表列出了Expression所有的方法,以及每个方法所对应的查询表达式及其限制。

方法描述
Expression.eq对应SQL的“field=value”表达式
如:Expression.eq(“name”,”zx”);
Expression.allEq方法的参数为一个Map类型对象,包含多个名/值对对应关系,相当于多个Expression.eq的叠加
Expression.gt对应SQL的“field>value”表达式
Expression.ge对应SQL的“field>=value”表达式
Expression.lt对应SQL的“field”表达式
Expression.le对应SQL的“field< =value”表达式
Expression.between对应SQL语句的between表达式,如:查询年龄在21与27岁之间的用户,可以写成Expression.between(“age”,new
Integer(21),new Integer(27));
Expression.like对应SQL语句的”field like value”表达式
Expression.in对应SQL语句的“field in(……)”表达式
Expression.eqProperty用于比较两个属性值,对应”field=field”SQL表达式
Expression.gtProperty用于比较两个属性值,对应”field>field”SQL表达式
Expression.geProperty用于比较两个属性值,对应”field>=field”SQL表达式
Expression.ltProperty用于比较两个属性值,对应”field表达式
Expression.leProperty用于比较两个属性值,对应”field< =field”SQL表达式
Expression.and对应SQL语句的And关系组合,如:Expression.and(Expression.eq(“name”,”zx”),Expression.eq(“sex”,”1”));
Expression.or对应SQL语句的Or关系组合,如:Expression.or(Expression.eq(“name”,”zx”),Expression.eq(“name”,”zhaoxin”));
Expression.sql作为补充这个方法提供了原生SQL语句查询的支持,在执行时直接通过原生SQL语句进行限定,如:Expression.sql(“lower({alias}.name)
like (?)”,“zhao%”,Hibernate.STRING) ;在运行时{ alias
}将会由当前查询所关联的实体类名替换,()中的?将会由”zhao%”替换,并且类型由Hibernate.STRING指定。

注意:Expression各方法中的属性参数(各方法中的第一个参数)所指定的属性名称(如:name,sex),并不是数据库表中的实际字段名称,而是实体对象中映射实际数据表字段的类属性名称。

2、示例查询:

示例查询是通过Example类来完成的,Example类实现了Criterion接口,可以用作Criteria查询条件,Example类的作用是:根据已有对象,查询属性值与之相同的其他对象。如下代码所示:

Criteria criteria=session.createCriteria(User.class);   User exampleuser=new User(“zx”);   criteria.add(Example.create(exampleuser));   List list=criteria.list();   for(int i=0;i   User user=(User)list.get(i);   System.out.println(user.getName()+”\n”);   }

上述代码中User exampleuser=new User(“zx”);criteria.add(Example.create(exampleuser));两句相当于 criteria.add(Expression.eq(“name”,”zx”));因此会生成类似如下的SQL语句:

select * from user where name=’zx’;

在上面的代码中exampleuser称为示例对象。

在Hibernate中队示例查询,默认情况下会排除掉示例对象中属性值为 空的属性,还可以调用Example.excludeNone(排除空串值)/excludeZeros(排除零值),或者调用 Example.excludeProperty方法来指定排除特定属性。

示例查询主要应用于组合查询中,比如根据用户输入的查询条件动态生成最终的查询语句,通过使用示例查询,可以避免由于查询条件过多而写的大量if判断语句。

3、复合查询:

复合查询主要是处理,具有关联关系的两个实体怎样进行关联查询,比如User实体对象与Addres实体对象具有一对多的关联关系,我们可以如下构造符合查询:

Criteria criteria=session.createCriteria(User.class);   Criteria addcriteria=criteria.createCriteria(“addresses”);(1)   addcriteria.add(Express.like(“address”,”%tianjin%”));     List list=criteria.list();   for(int i=0;i     User user=(User)list.get(i);     System.out.println(user.getName()+”\n”);     Set addresses=user.getAddresses();     Iterator it=addresses.iterator();     while(it.hasNext(){   Address address=(Address)it.next();   System.out.println(address.getAddress()+”\n”);     }   }

当执行到了(1)处时,表明要针对User对象的addresses属性添加新的查询条件,因此当执行criteria.list()时,Hibernate会生成类似如下的SQL语句:

Select * from user inner join address on user.id=address.id where   address.address like ‘%shanghai%’;

正如我们所见,我们可以通过向Criteria中添加保存关联对象的集合属性(addresses属性保存与User对象相关联的Address对象),来构造复合查询,在数据库一端是通过内连接查询来实现。

4、Criteria的高级特性:

A、限定返回记录条数:

我们可以通过利用Criteria.setFirstResult/setMaxResult方法来限定返回某一次查询的记录数,如下代码:

Criteria criteria=session.createCriteria(User.class);   criteria.setFirstResult(100);   criteria.setMaxResult(200);

通过以上代码可以设定该次查询返回user表中的从第100条记录开始直到第200条记录结束的100条记录。

B、对查询结果进行排序:

可通过使用net.sf.hibernate.expression.Order类可以对查询结果集进行排序,如下面代码:

Criteria criteria=session.createCriteria(User.class);   criteria.add(Expression.eq(“groupid”,”2”);   criteria.addOrder(Order.asc(“name”));   criteria.addOrder(Order.desc(“groupid”));   List list=criteria.list();

通过使用Order类的asc()/desc()方法,可以指定针对某个字段的排序逻辑,如果执行上述代码,会生成类似如下的SQL语句:

Select * from user where groupid=’2’ order by name asc,groupid desc

C、分组与统计:

在Hibernate3中,对Criteria又增添了新功能,可以支持分组与统计功能,在Hibernate3中增加了Projections以及ProjectionList类,这两个类对分组与统计功能进行了封装,如下代码:

Criteria criteria=session.createCriteria(User.class);   criteria.setProjection(Projections.groupProperty(“age”));(1)   List list=criteria.list();   Iterator it=list.iterator();   while(it.hasNext()){    System.out.println(it.next());   }

通过(1)处的代码,我们通过Projections类指定了用于分组的目标属性,当进行检索时Hibernate会生成类似如下的SQL语句:

Select age from user group by age;

还可以通过使用Projections的avg()/rowCount()/count()/max()/min()/countDistinct()等方法来实现统计功能,如下面的代码示例:

Criteria criteria=session.createCriteria(User.class);   criteria.setProjection(Projections.avg(“age”));(1)   List list=criteria.list();   Iterator it=list.iterator();   while(it.hasNext()){    System.out.println(it.next());   }

通过(1)处的代码,我们实现了对用户平均年龄的统计,当进行检索时,Hibernate会生成类似如下的SQL语句:

Select avg(age) from user;

另外,在SQL语句中的多条件分组与统计功能,可以利用ProjectionList类来实现,如下面代码所示:

Criteria criteria=session.createCriteria(User.class);   ProjectionList prolist=Projections.projectionList();   prolist.add(Projections.groupProperty(“age”));   prolist.add(Projections.rowCount());   criteria.setProjection(prolist);   List list=criteria.list();

通过以上代码,实现了对不同年龄人员数量的分组统计,当进行检索时,Hibernate会生成类似如下的SQL语句:

Select age,count(*) from user group by age;

5、DetachedCriteria:

在Hibernate2中,Criteria实例是与创建它的Session实例具有相同的生命周期的,也就是说,Session实例是它所创建的 Criteria实例的宿主,当Session关闭时,寄生于Session实例的Criteria都将失效。这就对Criteria的重用造成了困难, 为了实现Criteria实例的重用,在Hibernate3中提供了一个DetachedCriteria类,DetachedCriteria实例的 生命周期与Session实例的生命周期无关,我们可以利用DetachedCriteria对一些常用的Criteria查询条件进行抽离,当需要进行 检索时再与Session实例关联,从而获得运行期的Criteria实例。如下面的代码所示:

DetachedCriteria dc= DetachedCriteria.forClass(User.class);   dc.add(Expression.eq(“name”,”zhaoxin”));   dc.add(Expression.eq(“sex”,”1”));   Criteria criteria=dc.getExecutableCriteria(session);   Iterator it=criteria.list().iterator();   while(it.hasNext()){     User user=(User)it.next();     System.out.println(user.getName());   }

正如我们所见,DetachedCriteria的生存周期与session实例无关,当需要进行检索时,通过getExecutableCriteria(session)方法,与当前的Session实例关联并获得运行期的Criteria实例,完成检索。

DetachedCriteria也可以用于完成子查询功能,如下代码所示:

DetachedCriteria dc= DetachedCriteria.forClass(User.class);   dc.setProjection(Projections.avg(“age”));   Criteria criteria=session.createCriteria(User.class);   criteria.add(Subqueries.propertyGt(“age”,dc));   List list=criteria.list();

通过Subqueries类,实现了添加子查询的功能,我们将DetachedCriteria所设定的查询条件,当作子查询添加到了运行时Criteria实例的查询条件中,当执行检索时Hibernate会生成类似如下的SQL语句:

Select * from user where age>(select avg(age) from user group by age);
时间: 2024-11-08 21:24:02

hibernate—QBC的相关文章

hibernate QBC日期查询

使用QBC方式查询数据库,如果查询条件包含日期,则比较难以处理,尤其是在不是简单的在某个日期之前,或在某个日期之后的情况时,不能用hibernate常用方式,要用原生sql语句执行查询. 1.hibernate常用方式 方法                          说明        Restrictions.eq           =       Restrictions.allEq        利用Map来进行多个等于的限制        Restrictions.gt    

Hibernate QBC运算符

HQL运算符 QBC运算符 含义 = Restrictions.eq() 等于equal <> Restrictions.ne() 不等于not   equal > Restrictions.gt() 大于greater   than >= Restrictions.ge() 大于等于greater   than or equal < Restrictions.lt() 小于less   than <= Restrictions.le() 小于等于less   than

Hibernate QBC 分页

利用Hibernate 使用QUC分页其简单得功能为:1.通过输入第一条数据的位置和每页现实的数据来确定数据2.并可以通过输入页数来显示各个页数的数据程序主要代码:public void testPageQuery(){ SessionFactory sf = null; Session session0 = null; Transaction tx = null; try { while(true){ sf = HibernateUtil.getSessionFactory(); sessio

Hibernate QBC组合查询例子

Criteria criteria = session.createCriteria(Employee.class); //1. AND: 使用Conjunction表示 //Conjunction 本身就是一个Criterion对象 //且其中还可以添加Criterion对象 Conjunction conjunction = Restrictions.conjunction(); conjunction.add(Restrictions.like("name", "a&q

jeecg3.5 pom文件优化

<dependencies> <!-- activation --> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>${activation.version}</version> </dependency> <!-- aopalliance 

Jeecg Controller层的模版----自己的版本

自己修改了下Controller版本,改变原因, 1.msg面临的并发危险, 2.ModelAndView基本毫无作用的地位 3.ModelMap代替Request 出来的结果如图,使用了静态变量代替了view 效果如下: 模板是 package ${bussiPackage}.controller.${entityPackage}; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax

JEECG开发第一个菜单现实设备列表

一.新建设备表(t_base_device) SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for t_base_device -- ---------------------------- DROP TABLE IF EXISTS `t_base_device`; CREATE TABLE `t_base_device` ( `deviceid` int(10) NOT NULL, `d

Hibernate 查询方式(HQL/QBC/QBE)汇总

作为老牌的 ORM 框架,Hibernate 在推动数据库持久化层所做出的贡献有目共睹. 它所提供的数据查询方式也越来越丰富,从 SQL 到自创的 HQL,再到面向对象的标准化查询. 虽然查询方式有点眼花缭乱,配置使用起来也稍微有点复杂. 但是丝毫掩盖不了它迷人的地方,本篇博客试着汇总 Hibernate 所有的查询方式. 萝卜青菜各有所爱,工作中可以根据自己的喜好选择其中的几种进行编程. 1. HQL 方式,参数使用问号占位(4.1 版本中已被废弃) public List<UserPO>

Hibernate之QBC检索和本地SQL检索

QBC查询就是通过使用Hibernate提供的Query By Criteria API来查询对象,这种API封装了SQL语句的动态拼装,对查询提供了更加面向对象的功能接口 本地SQL查询来完善HQL不能涵盖所有的查询特性. ====================代码区====================== 测试类 1 package com.yl.hibernate.test; 2 3 4 import java.util.ArrayList; 5 import java.util.A