现在的位置: 首页 > 综合 > 正文

Hibernate中使用Criteria查询实例

2018年05月24日 ⁄ 综合 ⁄ 共 5120字 ⁄ 字号 评论关闭

Criteria查询是hibernate支持的一种java编写习惯的查询api。使用session建立net.sf.hibernate.Criteria,您可以在不用sql甚至hql的情况下进行查询。

AD:

hibernate支持一种java编写习惯的查询api,使用session建立net.sf.hibernate.Criteria,您可以在不用sql甚至hql的情况下进行查询。

如果我们要查询User的所有信息我们可以如下使用Criteria查询:

  1. Criteria crit = session.createCriteria(User.class);  
  2.         List users = crit.list();  
  3.         for (ListIterator iterator = users.listIterator(); iterator.hasNext(); ) {  
  4.             User user = (User) iterator.next();  
  5.             System.out.println("name: " + user.getName());  
  6.             System.out.println("age: " + user.getAge());             
  7.         }  

我们要为查询限定条件,可以通过net.sf.hibernate.expression.Expression设置Expression有很多的条件查询方法下面举一些例子:

  1. Criteria crit = session.createCriteria(User.class);  
  2.         crit.add(Expression.ge("age", new Integer(25)));  
  3.         List users = crit.list(); 

ge()表示大于等于,即age大于等于25的user。

  1. crit.add(Expression.gt("age", new Integer(20)));  
  2. crit.add(Expression.between("weight", new Integer(60),new Integer(80)));  
  3. List users = crit.list(); 

Criteria查询结果中的between表示weight在60和80之间。

  1. crit.add(Expression.or(  
  2.                    Expression.eq("age", new Integer(20)),  
  3.                    Expression.isNull("age")  
  4.                ));  
  5. List users = crit.list();  

eq表示age为20的user。

  1. Criteria crit = session.createCriteria(User.class);  
  2. crit.setFirstResult(51);  
  3. crit.setMaxResult(50);  
  4. List users = crit.list(); 

setMaxResult()设置返回的信息条数,setFirstResult()设置查询结果的初始位置,上面的程序段可以实现分页。

使用Criteria进行查询时,不仅仅能组合出SQL中where子句的功能,还可以组合出如排序、统计、分组等的查询功能。这就是Criteria进阶查询。

排序 

您可以使用Criteria进行查询,并使用org.hibernate.criterion.Order对结果进行排序,例如使用Oder.asc(),指定根据”age”由小到大排序(反之则使用desc()):

  1. Criteria criteria = session.createCriteria(User.class);  
  2. criteria.addOrder(Order.asc("age"));  
  3. List users = criteria.list(); 

注意在加入Order条件时,使用的是addOrder()方法,而不是add()方法,在产生SQL语句时,会使用order by与asc(desc)来进行排序指定:

Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ order by this_.age asc

限定查询笔数 

Criteria的setMaxResults()方法可以限定查询回来的笔数,如果配合setFirstResult()设定传回查询结果第一笔资料的位置,就可以实现简单的分页,例如传回第51笔之后的50笔资料(如果有的话):

  1. Criteria criteria = session.createCriteria(User.class);  
  2. criteria.setFirstResult(51);  
  3. criteria.setMaxResults(50);  
  4. List users = criteria.list(); 

根据您所指定得资料库,Hibernate将自动产生与资料库相依的限定笔数查询子句,例如在MySQL中,将使用limit产生以下的SQL语句:

Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ limit ?, ?

统计动作 

您可以对查询结果进行统计动作,使用 org.hibernate.criterion.Projections的avg()、rowCount()、count()、max()、min ()、 countDistinct()等方法,再搭配Criteria的setProjection()方法加入条件设定,例如对查询结果的"age"作平均:

  1. Criteria criteria = session.createCriteria(User.class);  
  2. criteria.setProjection(Projections.avg("age"));  
  3. List users = criteria.list(); 

上面的程式将由Hibernate自动产生SQL的avg函数进行平均计算:

Hibernate: select avg(this_.age) as y0_ from T_USER this_

分组 

还可以配合Projections的groupProperty()来对结果进行分组,例如以"age"进行分组,也就是如果资料中"age"如果有 20、20、25、30,则以下会显示20、25、30:

  1. Criteria criteria = session.createCriteria(User.class);  
  2. criteria.setProjection(Projections.groupProperty("age"));  
  3. List users = criteria.list(); 

上面的程式将由Hibernate自动产生SQL的group by子句进行分组计算:

Hibernate: select this_.age as y0_ from T_USER this_ group by this_.age

如果想同时结合统计与分组功能,则可以使用org.hibernate.criterion.ProjectionList,例如下面的程式会计算每个年龄各有多少个人:

  1. ProjectionList projectionList = Projections.projectionList();  
  2. projectionList.add(Projections.groupProperty("age"));  
  3. projectionList.add(Projections.rowCount());  
  4.  
  5.  
  6. Criteria criteria = session.createCriteria(User.class);  
  7. criteria.setProjection(projectionList);  
  8. List users = criteria.list();  

观察所产生的SQL语句,将使用group by先进行分组,再针对每个分组进行count函数的计数,

Hibernate: select this_.age as y0_, count(*) as y1_ from T_USER this_ group by this_.age

根据已知物件进行查询 

设定查询条件并非一定要使用Restrictions,如果属性条件很多,使用Restrictions也不方便,如果有一个已知的物件,则可以根据这个物件作为查询的依据,看看是否有属性与之类似的物件,例如:

  1. User user = new User();  
  2. user.setAge(new Integer(30));  
  3.  
  4. Criteria criteria = session.createCriteria(User.class);  
  5. criteria.add(Example.create(user));  
  6.  
  7. List users = criteria.list();  

Criteria进阶查询中,您可以透过 org.hibernate.criterion.Example的create()方法来建立Example实例,Example实作了 Criteria介面,因此可以使用add()方法加入至Criteria条件设定之中,Hibernate将自动过滤掉空属性,根据已知物件上已设定的属性,判定是否产生于where子句之中:

Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where (this_.age=?)

设定SQL范本 

如果您了解如何撰写SQL语句,想要设定一些Hibernate产生SQL时的范本,您也可以使用Restrictions的sqlRestriction()方法,提供SQL语法范本作限定查询,例如查询name以cater开头的资料:

  1. Criteria criteria = session.createCriteria(User.class);  
  2. criteria.add(Restrictions.sqlRestriction(  
  3. "{alias}.name LIKE (?)", "cater%", Hibernate.STRING));  
  4. List users = criteria.list(); 

其中alias将被替换为与User类别相关的名称,而? 将被替换为cater%,也就是第二个参数所提供的值,sqlRestriction()方法第一个参数所设定的是where子句的部份,所以在SQL撰写时,不必再写where,观察所产生的SQL语句,将使用您所设定的SQL范本作为基础,来完成SQL的条件查询:

Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.name LIKE (?)

如果有多个查询条件,例如between子句的查询,则可以如下:

  1. Criteria criteria = session.createCriteria(User.class);  
  2. Integer[] ages = {new Integer(20), new Integer(40)};  
  3. Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};  
  4. criteria.add(Restrictions.sqlRestriction(  
  5. "{alias}.age BETWEEN (?) AND (?)", ages, types));  
  6. List users = criteria.list(); 

观察所产生的SQL语句如下:

Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.age BETWEEN (?) AND (?)

抱歉!评论已关闭.