欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java的Hibernate框架中Criteria查询使用的实例讲解

程序员文章站 2024-03-08 19:56:40
我们讲一下criteria查询,这个对于不是太熟悉sql语句的我们这些程序员来说是很容易上手的。  废话不多说,看一下例子:  实体类如下:...

我们讲一下criteria查询,这个对于不是太熟悉sql语句的我们这些程序员来说是很容易上手的。
 废话不多说,看一下例子:
 实体类如下:

public class user implements serializable{ 
 
  private static final long serialversionuid = 1l; 
  public long id; 
  private string name; 
  private int age; 
    //省略get/set方法 
} 

  映射文件我们就不写了,很简单的一个实体,如果不懂的童鞋请参照我在hibernate分类中的其他文章。
 接下来我们看如何使用criteria来进行查询:
 

public static void main(string[] args) { 
 
  configuration cfg = new configuration().configure(); 
  sessionfactory sessionfactory = cfg.buildsessionfactory(); 
  session session = sessionfactory.opensession(); 
   
  criteria criteria = session.createcriteria(user.class); 
  criteria.add(restrictions.eq("name","shun")); 
   
  list list = criteria.list(); 
  iterator iter = list.iterator(); 
  while(iter.hasnext()) { 
    user user = (user)iter.next(); 
    system.out.println(user.getname()+":"+user.getage()); 
  } 
   
  session.close(); 
} 

  看到代码,很简单的一串。
 前面都很熟悉啦,我们看到构造session之后的代码:
 

criteria criteria = session.createcriteria(user.class); 
criteria.add(restrictions.eq("name","shun")); 

  这两句代码是重点,我们来分析一下,究竟是什么意思?
 第一句我们通过session得到criteria实现类的一个对象,接着第二句我们通过add方法添加一个条件,eq表示相等。在hibernate3以前是通过expression.eq来实现,3之后由于criteria被抛弃,我们改用restrictions类来实现,它和expression一样的用法。我们看看api发现expression继承于restrictions。
 回到我们上面的两句,我们做完这些工作后,实际上hibernate帮我们构造了类似

 select * from user where name='shun' 

  这样的语句。(这里我们映射文件中user类对应的表是user表,而name属性对应的是name字段)
 
 restrictions还有许多帮助我们构造sql语句的方法,大家查一下api很容易就可以理解了。
 
 我们重新看一下上面的代码,如果我们关闭了session,但是我们想继续使用这个criteria,行吗?我们来看一下。
 在上面的代码之后,我们重新遍历,加上:
 

list list2 = criteria.list(); 
iterator iter2 = list.iterator(); 
while(iter.hasnext()) { 
  user user = (user)iter.next(); 
  system.out.println(user.getname()+":"+user.getage()); 
} 

  为了区分跟上一个list和iter的区别,我们这里用另外一个。
 运行它,我们得到的是一个异常:
 

org.hibernate.sessionexception: session is closed! 

  报这个异常表示session已经关闭,很多情况下我们在关闭了session再进行saveorupdate,save等跟持久化相关的操作都会报类似的异常。
 hibernate3考虑到了我们这个需求,它实现了一个detachedcriteria,这个可以独立于session而存在。
 我们来看一下例子:(实体还是上面的)
 

public static void main(string[] args) { 
     
    configuration cfg = new configuration().configure(); 
    sessionfactory sessionfactory = cfg.buildsessionfactory(); 
    session session = sessionfactory.opensession(); 
     
    detachedcriteria decriteria = detachedcriteria.forclass(user.class); 
    decriteria.add(restrictions.eq("name","shun")); 
     
    list list = decriteria.getexecutablecriteria(session).list(); 
    iterator iter = list.iterator(); 
    while(iter.hasnext()) { 
      user user = (user)iter.next(); 
      system.out.println(user.getname()+":"+user.getage()); 
    } 
     
    session.close(); 
     
    session session2 = sessionfactory.opensession(); 
    list list2 = decriteria.getexecutablecriteria(session2).list(); 
    iterator iter2 = list2.iterator(); 
    while(iter2.hasnext()) { 
      user user = (user)iter2.next(); 
      system.out.println(user.getname()+":"+user.getage()); 
    } 
  } 

  我们看到在session关闭之后,我们在另外一个连接中还是可以继续用detachedcriteria。我们需要通过getexecutablecriteria(session session)把当前的detachedcriteria跟某一个session进行关联。
 
 
 接下来我们再来看一下subqueries类与detachedcriteria的结合使用:
 

public static void main(string[] args) { 
     
    configuration cfg = new configuration().configure(); 
    sessionfactory sessionfactory = cfg.buildsessionfactory(); 
    session session = sessionfactory.opensession(); 
     
    detachedcriteria decriteria = detachedcriteria.forclass(user.class); 
    decriteria.setprojection(projections.avg("age")); 
     
    criteria criteria = session.createcriteria(user.class); 
    criteria.add(subqueries.propertygt("age",decriteria)); 
    list list = criteria.list(); 
    iterator iter = list.iterator(); 
    while(iter.hasnext()) { 
      user user = (user)iter.next(); 
      system.out.println(user.getname()+":"+user.getage()); 
    } 
     
    session.close(); 
     
  } 

  估计大家有疑问的应该是第一句代码:
 

decriteria.setprojection(projections.avg("age")); 

  这句代码是指通过decriteria得到age的平均值。然后在下面取得大于平均值的age的对象。
 projections包含了许多实现sql方法的封装方法,大家可以看一下api。

下面我们来了解一下它的稍微高级点的用法。
 直接看代码吧:

criteria.setfirstresult(10); 
criteria.setmaxresults(20); 

  这里我们设置了开始的记录是第10条,然后从第10条开始查出20条记录,根据这个做法,我们就可以实现基本的分页功能了。
 当然,我们在很多情况下都需要排序,criteria也是支持的:

 criteria.addorder(order.desc("age")); 

  这里,我们直接用addorder方法即可,里面通过order.desc得到一个order对象,它需要一个属性参数。实际上当我们调用addorder时,hibernate会帮我们生成order by age,这样的语句。
 
 当我们需要进行分组时,这个怎么做呢?这个就需要用到我们上次有涉及到的projections这个类的groupproperty方法,
 

criteria.setprojection(projections.groupproperty("age")); 

  这里我们就根据age属性来进行分组,实际上也就是通过age对应的字段age进行分组,hibernate会自动帮我们转换成group by age这样的语句。
projections中有许多实用的方法(注意,此为是hibernate 3后才有的)。