﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-读万卷书不如行千里路，经验的积累又不是一蹴而就的，不但需要知识的沉积，还需要长久经验的总结升华-文章分类-Hibernate技术</title><link>http://www.blogjava.net/liujw/category/9477.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 08:49:27 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 08:49:27 GMT</pubDate><ttl>60</ttl><item><title>Hibernate综合查询解决方案</title><link>http://www.blogjava.net/liujw/articles/39138.html</link><dc:creator>刘军伟</dc:creator><author>刘军伟</author><pubDate>Tue, 04 Apr 2006 05:31:00 GMT</pubDate><guid>http://www.blogjava.net/liujw/articles/39138.html</guid><wfw:comment>http://www.blogjava.net/liujw/comments/39138.html</wfw:comment><comments>http://www.blogjava.net/liujw/articles/39138.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liujw/comments/commentRss/39138.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liujw/services/trackbacks/39138.html</trackback:ping><description><![CDATA[    这两个星期以来，我把原来用struts开发的一个测试工具改用struts+hibernate来实现，首先从心情上来，整个开发过程中始终保持愉快和平和，“原来开发可以这样愉快？”，再一点就是开发效率上高效了许多。<br />      现在sun又加入jdocentral.com开始着手JDO2.0，想想看等它出台以后将是一个怎样激动人心得场面，让我们拭目以待。<br />      <br />      用Hibernate来操纵持久数据非常简单，在这里一些简单的查询我会一笔带过，本文着重说明在综合查询兼有分页的时候我的一些经验，如果网友觉得我的方案还有不足的地方，也请和我讨论，我的email:plateau_t@sina.com.<br />      <br />      第一部分：Hibernate提供的查询接口或其方法（此部分不做深究，请参考hibernate手册）<br />      <br />       1。根据ID查询<br />    要用到Session接口的load方法。<br />    load(Class theClass, Serializable id) <br />    load(Class theClass, Serializable id, LockMode lockMode)<br />    load(Object object, Serializable id)  <br />    <br />       2。HQL语句进行查询<br />       <br />       2。1 利用Query接口，Query由Session里的createQuery()来产生一个查询<br />        1)不带参数的查询（这类比较简单）<br />        Query query=session.createQuery("select user from User as user");<br />        2)带参数的查询<br />        Query query=session.createQuery("select user from User as user where user.name=?");<br />        query.setString(0,name)//假设name为传过来的参数<br />        Query query=session.createQuery("select user from User as user where user.name=:name");<br />        query.setString("name",name)//假设name为传过来的参数 <br />        (多个参数以此类推) <br />        <br />        利用Session接口的find查询<br />        find(String query) <br />        find(String query, Object[] values, Type[] types) <br />        find(String query, Object value, Type type)    均返回list   <br />        如:<br />        List list=session.find("select user from Users as user where user.name=?",name,Hibernate.STRING)<br />        List list=session.find("select user from Users as user where user.name=? and             user.pw=?",new Object[]{name,pw},new Type[]{Hibernate.STRING,Hibernate.STRING})<br />        <br />        {推荐使用Query的方法进行查询}   <br />        <br />      第二部分：hibernate综合查询解决方案 （此部分详细实例说明，如有不足的地方请写信给我）         <br />      <br />       大家从第一部分可以看到，带有参数的查询，必须使用到Query接口,如上边：<br />        Query query=session.createQuery("select users from Users as users where users.name=?");<br />        query.setString(0,name)//假设name为传过来的参数    <br />       但是在系统中如何才能写一个公用的查寻方法呢？咋一看，似乎是不可以的，因为每一次查询的参数不一样，参数的数量不一样（如下代码），那么我们如何提取共性呢？   <br />         Query query=session.createQuery("select users from Users as users where users.name=? and users.pw=?");<br />        query.setString(0,name)//假设name为传过来的参数  <br />        query.setString(1,pw); <br />       <br />      首先说明，我的解决方案是从Seesion接口的find方法找到出口的，如下为Session接口得find()方法之一：<br />        find(String query, Object[] values, Type[] types)  <br />      其中Object[]为存放参数值的数组，Type[]为存放参数类型的数组，他们的顺序是和query里“？” 的顺序是相同的。那么我为什么不用该find方法呢，因为如果有分页的情况，那么该方法将不适用。<br />    <br />      下面详细要说明的解决方案：<br />      首先我想创建三个新的对象：Paras.java（参数对象） ParasList.java（参数集合对象）HQuery.java<br />     （感谢我的同事camel提供注释良好的代码）<br />     1。Paras.java（参数对象）<br />    <br />  package com.ifreeway.homegrown.testing.waf;<br />  <br />  /**<br />   *<br />   * &lt;p&gt;Title:定义一个sql语句的条件参数类 &lt;/p&gt;<br />   * &lt;p&gt;Description: 可以使用有序的参数集合传送给sql/hql语句 &lt;/p&gt;<br />   * &lt;p&gt;Copyright: Copyright (c) 2003&lt;/p&gt;<br />   * &lt;p&gt;Company: ifreeway&lt;/p&gt;<br />   * @author camel<br />   * @version 1.0<br />   */<br />  <br />  public class Paras {<br />   /**<br />    * 参数名称<br />    */<br />   private Object pName;<br />   /**<br />    * 参数类型编码，于java.sql.types中的类型保持一致<br />    */<br />   private int typeNo;<br />  <br />   public Object getPName() {<br />    return pName;<br />   }<br />   public void setPName(Object pName) {<br />    this.pName = pName;<br />   }<br />   public int getTypeNo() {<br />    return typeNo;<br />   }<br />   public void setTypeNo(int typeNo) {<br />    this.typeNo = typeNo;<br />   }<br />  }  <br /> <br /> 2。ParasList.java（参数集合对象） <br />  package com.ifreeway.homegrown.testing.waf;<br />  <br />  import java.util.ArrayList;<br />  <br />  /**<br />   *<br />   * &lt;p&gt;Title: 参数集合类&lt;/p&gt;<br />   * &lt;p&gt;Description: 封装sql/hql的参数到该集合类，便于处理和传递&lt;/p&gt;<br />   * &lt;p&gt;Copyright: Copyright (c) 2003&lt;/p&gt;<br />   * &lt;p&gt;Company: ifreeway&lt;/p&gt;<br />   * @author camel<br />   * @version 1.0<br />   */<br />  <br />  public class ParaList extends ArrayList {<br />  <br />    /**<br />     * 在指定位置添加一个参数对象<br />     * @param index：参数的索引值<br />     * @param p：需要加入的参数对象<br />     */<br />    public  void addParas(int index,Paras p){<br />        super.add(index,p);<br />    }<br />  <br />    /**<br />     * 在集合的最后位置添加一个参数对象<br />     * @param p：需要加入的参数对象<br />     */<br />    public void addParas(Paras p){<br />      super.add(p);<br />    }<br />  <br />    /**<br />     * 取得指定位置的参数对象<br />     * @param index：参数的索引值<br />     * @return：参数对象<br />     */<br />    public Paras getParas(int index){<br />        return (Paras)super.get(index) ;<br />    }<br />    /**<br />     * 取得指定参数的索引<br />     * @param p：参数对象<br />     * @return：参数索引<br />     */<br />    public int indexofParas(Paras p){<br />       return super.indexOf(p) ;<br />    }<br />  <br />    /**<br />     * 从集合中去掉一个指定的参数对象<br />     * @param index：参数索引<br />     */<br />    public void removeParas(int index){<br />      super.remove(index) ;<br />    } <br />  <br />  }  <br /> 3。HQuery.java<br />  package com.ifreeway.homegrown.testing.waf;<br />  <br />  <br />  /**<br />   *<br />   * &lt;p&gt;Title: HQL的语句封装类&lt;/p&gt;<br />   * &lt;p&gt;Description: 该对象封装HQL的查询语句，参数集合，排序参数，分组参数，单页起始地址  &lt;/p&gt;<br />   * &lt;p&gt;Copyright: Copyright (c) 2003&lt;/p&gt;<br />   * &lt;p&gt;Company:ifreeway &lt;/p&gt;<br />   * @author camel<br />   * @version 1.0<br />   */<br />  <br />  public class HQuery {<br />  <br />    /**<br />     * HQL查询语句<br />     */<br />    private String queryString;<br />    /**<br />     * 参数集合对象<br />     */<br />    private ParaList paralist;<br />    /**<br />     * 排序字段<br />     */<br />    private String orderby;<br />    /**<br />     * 分组字段<br />     */<br />    private String groupby;<br />    /**<br />     * 分页起始查询地址<br />     */<br />    private int pageStartNo;<br />  <br />    /**<br />     * 取得一个Hibernate的Query对象<br />     * @return：Query对象<br />     */<br />    public String getQueryString() {<br />      return queryString;<br />    }<br />  <br />    /**<br />     * 设置一个HQL查询字符串<br />     * @param queryString：查询字符串<br />     * <br />     */<br />    public void setQueryString(String queryString) {<br />   <br />     this.queryString =queryString;<br />  <br />    }<br />  <br />    /**<br />     * 取得参数集合对象<br />     * @return：参数集合对象<br />     */<br />    public ParaList getParalist() {<br />      return paralist;<br />    }<br />  <br />    /**<br />     * 设置参数集合对象<br />     * @param paralist：参数集合对象<br />     */<br />    public void setParalist(ParaList paralist) {<br />      this.paralist = paralist;<br />    }<br />  <br />    /**<br />     * 取得排序字段<br />     * @return：排序字段<br />     */<br />    public String getOrderby() {<br />      return orderby;<br />    }<br />  <br />    /**<br />     * 设置排序字段<br />     * @param orderby<br />     */<br />    public void setOrderby(String orderby) {<br />      this.orderby = orderby;<br />    }<br />  <br />    /**<br />     * 取得分组字段<br />     * @return<br />     */<br />    public String getGroupby() {<br />      return groupby;<br />    }<br />  <br />    /**<br />     * 设置分组字段<br />     * @param groupby<br />     */<br />    public void setGroupby(String groupby) {<br />      this.groupby = groupby;<br />    }<br />  <br />    /**<br />     * 取得页起始地址<br />     * @return<br />     */<br />    public int getPageStartNo() {<br />      return pageStartNo;<br />    }<br />  <br />    /**<br />     * 设置页起始地址<br />     * @param pageStartNo<br />     */<br />    public void setPageStartNo(int pageStartNo) {<br />      this.pageStartNo = pageStartNo;<br />    }<br />  } <br />  <br /> 上面三个对象的关系是：<br /> <br /> 用Paras来装载每一个查询参数<br />  Paras paras=new Paras();<br />  paras.setPName(...);<br />  paras.setTypeNo(...);<br /> 然后放在ParasList中<br />  ParasList paraslist=new ParasList();<br />  paraslist.add(paras)<br /> 最后把填充以后的ParasList集合给HQuery  <br />  HQuery hquery=new HQuery();<br />  hquery.setParalist(paraslist);<br />  <br /> 先面我们写一个公用查寻方法，来实现我们的综合查询：<br /> <br /> /**<br />  *<br />  *  综合查询，首先实例化HQuery<br />  * @see com.ifreeway.homegrown.testing.common.waf.DBHandler#find(com.ifreeway.homegrown.testing.common.waf.HQuery)<br />  */<br /> public List find(HQuery _query) throws HibernateException {<br />  List itr = null;<br />  try {<br />   StringBuffer query_str = new StringBuffer(_query.getQueryString());<br />   //是否要排序<br />   if (_query.getOrderby() != null) {<br />    query_str.append(_query.getOrderby());<br />   }<br />   //是否要分组<br />   if (_query.getGroupby() != null) {<br />    query_str.append(_query.getGroupby());<br />   }<br />   Session session = getSession();<br />   Query query = session.createQuery(query_str.toString());<br />   if (_query.getParalist() != null) {<br />    List list = _query.getParalist();<br />    for (int i = 0; i &lt; list.size(); i++) {<br />     Paras param = (Paras) list.get(i);<br />     switch (param.getTypeNo()) {//此处要根据参数类型的增加要增加相应的“case”<br />      case Types.VARCHAR :<br />       query.setString(i, param.getPName().toString());<br />       break;<br />      case Types.INTEGER :<br />       query.setInteger(<br />        i,<br />        ((Integer) param.getPName()).intValue());<br />       break;<br />      case Types.DATE :<br />       query.setDate(i, (java.sql.Date) param.getPName());<br />       break;<br />      case Types.DOUBLE :<br />       query.setDouble(<br />        i,<br />        ((Double) param.getPName()).doubleValue());<br />       break;<br />      case Types.BOOLEAN :<br />       query.setBoolean(<br />        i,<br />        ((Boolean) param.getPName()).booleanValue());<br />       break;<br />      case Types.CHAR :<br />       query.setCharacter(<br />        i,<br />        ((Character) param.getPName()).charValue());<br />       break;<br />      case Types.JAVA_OBJECT :<br />       query.setEntity(i, (BaseModel) param.getPName());<br />       break;<br />     }<br />    }<br />   }<br />   //是否存在分页，当_query.getPageStartNo()==0是不分页<br />   if (_query.getPageStartNo() != 0) {<br />    int pageno = _query.getPageStartNo();<br />    query.setFirstResult((pageno - 1) * Constants.RECORD_PER_PAGE);<br />    query.setMaxResults((pageno) * Constants.RECORD_PER_PAGE);<br />   }<br />   itr = query.list();<br />   closeSession();<br />  } catch (Exception e) {<br /><br />  }<br />  return itr;<br /> } <br />    <br />      好了一旦我们做好了上边的工作，查询对我们来说将是很容易的一件事情，而且可以达到公用，是不是省了许多力气？下面我将实例化一个例子来进一步说明：<br />      <br />      例子：<br />      HQuery hquery=HQuery();<br />      hquery.setQueryString("select users from Users as users where users.name=? and users.sex=?");<br />      hquery.setOrderby("order by users.age desc");<br />      <br />      //如果要分页，把当前页curpage传递给hquery<br />      hquery.setPageStartNo(curpage);<br />      <br />      //实例化参数，本例为两个参数<br />      Paras paras1=new Paras();<br />      paras1.setPName(name);<br />      paras1.setTypeNo(Types.VARCHAR);<br />      <br />      Paras paras2=new Paras();<br />      paras2.setPName(sex);<br />      paras2.setTypeNo(Types.INTEGER);<br />      <br />      ParasList paraslist=new ParasList();<br />      paraslist.add(paras1);<br />      paraslist.add(paras2);//注意顺序<br />      <br />      hquery.setParalist(paraslist);<br />      <br />      //好了，做好准备工作，调用查寻方法得到结果<br />      List list=find(hquery);<br /><img src ="http://www.blogjava.net/liujw/aggbug/39138.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liujw/" target="_blank">刘军伟</a> 2006-04-04 13:31 <a href="http://www.blogjava.net/liujw/articles/39138.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>