龙行天下

  政 博
随笔 - 23, 文章 - 0, 评论 - 12, 引用 - 0
数据加载中……

Hibernate查询解决方案

第一部分: Hibernate 提供的查询接口或其方法 (此部分不做深究,请参考 hibernate 手册)
     
       1
。根据 ID 查询
    
要用到 Session 接口的 load 方法。
    load(Class theClass, Serializable id)
    load(Class theClass, Serializable id, LockMode lockMode)
    load(Object object, Serializable id) 
    
       2
HQL 语句进行查询
      
       2
1 利用 Query 接口, Query Session 里的 createQuery() 来产生一个查询
        1)
不带参数的查询(这类比较简单)
        Query query=session.createQuery("select user from User as user");
        2)
带参数的查询
        Query query=session.createQuery("select user from User as user where user.name=?");
        query.setString(0,name)//
假设 name 为传过来的参数
        Query query=session.createQuery("select user from User as user where user.name=:name");
        query.setString("name",name)//
假设 name 为传过来的参数
        (
多个参数以此类推
)
       
       
利用 Session 接口的 find 查询

        find(String query)
        find(String query, Object[] values, Type[] types)
        find(String query, Object value, Type type)   
均返回 list  
       
:
        List list=session.find("select user from Users as user where user.name=?",name,Hibernate.STRING)
        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})
       
        {
推荐使用 Query 的方法进行查询
}  
       
     
第二部分: hibernate 综合查询解决方案 (此部分详细实例说明,如有不足的地方请写信给我)
        
     
       
大家从第一部分可以看到,带有参数的查询,必须使用到 Query 接口 , 如上边:

        Query query=session.createQuery("select users from Users as users where users.name=?");
        query.setString(0,name)//
假设 name 为传过来的参数    
       
但是在系统中如何才能写一个公用的查寻方法呢?咋一看,似乎是不可以的,因为每一次查询的参数不一样,参数的数量不一样(如下代码),那么我们如何提取共性呢?
   
         Query query=session.createQuery("select users from Users as users where users.name=? and users.pw=?");
        query.setString(0,name)//
假设 name 为传过来的参数
 
        query.setString(1,pw);
      
     
首先说明,我的解决方案是从 Seesion 接口的 find 方法找到出口的,如下为 Session 接口得 find() 方法之一:

        find(String query, Object[] values, Type[] types) 
     
其中 Object[] 为存放参数值的数组, Type[] 为存放参数类型的数组,他们的顺序是和 query 的顺序是相同的。那么我为什么不用该 find 方法呢,因为如果有分页的情况,那么该方法将不适用。
    
     
下面详细要说明的解决方案:
     
首先我想创建三个新的对象: Paras.java (参数对象) ParasList.java (参数集合对象) HQuery.java
    
(感谢我的同事 camel 提供注释良好的代码)

     1
Paras.java (参数对象)
    
  package com.ifreeway.homegrown.testing.waf;
  
  /**
   *
   * <p>Title:
定义一个 sql 语句的条件参数类 </p>
   * <p>Description:
可以使用有序的参数集合传送给 sql/hql 语句
</p>
   * <p>Copyright: Copyright (c) 2003</p>
   * <p>Company: ifreeway</p>
   * @author camel
   * @version 1.0
   */
  
  public class Paras {
   /**
    *
参数名称

    */
   private Object pName;
   /**
    *
参数类型编码,于 java.sql.types 中的类型保持一致
    */
   private int typeNo;
  
   public Object getPName() {
    return pName;
   }
   public void setPName(Object pName) {
    this.pName = pName;
   }
   public int getTypeNo() {
    return typeNo;
   }
   public void setTypeNo(int typeNo) {
    this.typeNo = typeNo;
   }
  } 
 
 2
ParasList.java (参数集合对象)  
  package com.ifreeway.homegrown.testing.waf;
  
  import java.util.ArrayList;
  
  /**
   *
   * <p>Title:
参数集合类
</p>
   * <p>Description:
封装 sql/hql 的参数到该集合类,便于处理和传递
</p>
   * <p>Copyright: Copyright (c) 2003</p>
   * <p>Company: ifreeway</p>
   * @author camel
   * @version 1.0
   */
  
  public class ParaList extends ArrayList {
  
    /**
     *
在指定位置添加一个参数对象

     * @param index
:参数的索引值
     * @param p
:需要加入的参数对象
     */
    public  void addParas(int index,Paras p){
        super.add(index,p);
    }
  
    /**
     *
在集合的最后位置添加一个参数对象
     * @param p
:需要加入的参数对象
     */
    public void addParas(Paras p){
      super.add(p);
    }
  
    /**
     *
取得指定位置的参数对象
     * @param index
:参数的索引值
     * @return
:参数对象
     */
    public Paras getParas(int index){
        return (Paras)super.get(index) ;
    }
    /**
     *
取得指定参数的索引
     * @param p
:参数对象
     * @return
:参数索引
     */
    public int indexofParas(Paras p){
       return super.indexOf(p) ;
    }
  
    /**
     *
从集合中去掉一个指定的参数对象
     * @param index
:参数索引
     */
    public void removeParas(int index){
      super.remove(index) ;
    } 
  
  } 
 3
HQuery.java
  package com.ifreeway.homegrown.testing.waf;
  
  
  /**
   *
   * <p>Title: HQL
的语句封装类
</p>
   * <p>Description:
该对象封装 HQL 的查询语句,参数集合,排序参数,分组参数,单页起始地址
  </p>
   * <p>Copyright: Copyright (c) 2003</p>
   * <p>Company:ifreeway </p>
   * @author camel
   * @version 1.0
   */
  
  public class HQuery {
  
    /**
     * HQL
查询语句

     */
    private String queryString;
    /**
     *
参数集合对象
     */
    private ParaList paralist;
    /**
     *
排序字段
     */
    private String orderby;
    /**
     *
分组字段
     */
    private String groupby;
    /**
     *
分页起始查询地址
     */
    private int pageStartNo;
  
    /**
     *
取得一个 Hibernate Query 对象
     * @return
Query 对象
     */
    public String getQueryString() {
      return queryString;
    }
  
    /**
     *
设置一个 HQL 查询字符串
     * @param queryString
:查询字符串
     *
     */
    public void setQueryString(String queryString) {
  
     this.queryString =queryString;
  
    }
  
    /**
     *
取得参数集合对象
     * @return
:参数集合对象
     */
    public ParaList getParalist() {
      return paralist;
    }
  
    /**
     *
设置参数集合对象
     * @param paralist
:参数集合对象
     */
    public void setParalist(ParaList paralist) {
      this.paralist = paralist;
    }
  
    /**
     *
取得排序字段
     * @return
:排序字段
     */
    public String getOrderby() {
      return orderby;
    }
  
    /**
     *
设置排序字段
     * @param orderby
     */
    public void setOrderby(String orderby) {
      this.orderby = orderby;
    }
  
    /**
     *
取得分组字段
     * @return
     */
    public String getGroupby() {
      return groupby;
    }
  
    /**
     *
设置分组字段
     * @param groupby
     */
    public void setGroupby(String groupby) {
      this.groupby = groupby;
    }
  
    /**
     *
取得页起始地址
     * @return
     */
    public int getPageStartNo() {
      return pageStartNo;
    }
  
    /**
     *
设置页起始地址
     * @param pageStartNo
     */
    public void setPageStartNo(int pageStartNo) {
      this.pageStartNo = pageStartNo;
    }
  } 
  
 
上面三个对象的关系是:
 
 
Paras 来装载每一个查询参数
  Paras paras=new Paras();
  paras.setPName(...);
  paras.setTypeNo(...);
 
然后放在 ParasList
  ParasList paraslist=new ParasList();
  paraslist.add(paras)
 
最后把填充以后的 ParasList 集合给 HQuery 
  HQuery hquery=new HQuery();
  hquery.setParalist(paraslist);
  
 
先面我们写一个公用查寻方法,来实现我们的综合查询:

 
 /**
  *
  * 
综合查询,首先实例化 HQuery
  * @see com.ifreeway.homegrown.testing.common.waf.DBHandler#find(com.ifreeway.homegrown.testing.common.waf.HQuery)
  */
 public List find(HQuery _query) throws HibernateException {
  List itr = null;
  try {
   StringBuffer query_str = new StringBuffer(_query.getQueryString());
   //
是否要排序

   if (_query.getOrderby() != null) {
    query_str.append(_query.getOrderby());
   }
   //
是否要分组
   if (_query.getGroupby() != null) {
    query_str.append(_query.getGroupby());
   }
   Session session = getSession();
   Query query = session.createQuery(query_str.toString());
   if (_query.getParalist() != null) {
    List list = _query.getParalist();
    for (int i = 0; i < list.size(); i++) {
     Paras param = (Paras) list.get(i);
     switch (param.getTypeNo()) {//
此处要根据参数类型的增加要增加相应的 “case”
      case Types.VARCHAR :
       query.setString(i, param.getPName().toString());
       break;
      case Types.INTEGER :
       query.setInteger(
        i,
        ((Integer) param.getPName()).intValue());
       break;
      case Types.DATE :
       query.setDate(i, (java.sql.Date) param.getPName());
       break;
      case Types.DOUBLE :
       query.setDouble(
        i,
        ((Double) param.getPName()).doubleValue());
       break;
      case Types.BOOLEAN :
       query.setBoolean(
        i,
        ((Boolean) param.getPName()).booleanValue());
       break;
      case Types.CHAR :
       query.setCharacter(
        i,
        ((Character) param.getPName()).charValue());
       break;
      case Types.JAVA_OBJECT :
       query.setEntity(i, (BaseModel) param.getPName());
       break;
     }
    }
   }
   //
是否存在分页,当 _query.getPageStartNo()==0 是不分页

   if (_query.getPageStartNo() != 0) {
    int pageno = _query.getPageStartNo();
    query.setFirstResult((pageno - 1) * Constants.RECORD_PER_PAGE);
    query.setMaxResults((pageno) * Constants.RECORD_PER_PAGE);
   }
   itr = query.list();
   closeSession();
  } catch (Exception e) {

  }
  return itr;
 } 
    
     
好了一旦我们做好了上边的工作,查询对我们来说将是很容易的一件事情,而且可以达到公用,是不是省了许多力气?下面我将实例化一个例子来进一步说明:

     
     
例子:
      HQuery hquery=HQuery();
      hquery.setQueryString("select users from Users as users where users.name=? and users.sex=?");
      hquery.setOrderby("order by users.age desc");
     
      //
如果要分页,把当前页 curpage 传递给 hquery
      hquery.setPageStartNo(curpage);
     
      //
实例化参数,本例为两个参数

      Paras paras1=new Paras();
      paras1.setPName(name);
      paras1.setTypeNo(Types.VARCHAR);
     
      Paras paras2=new Paras();
      paras2.setPName(sex);
      paras2.setTypeNo(Types.INTEGER);
     
      ParasList paraslist=new ParasList();
      paraslist.add(paras1);
      paraslist.add(paras2);//
注意顺序
     
      hquery.setParalist(paraslist);
     
      //
好了,做好准备工作,调用查寻方法得到结果
      List list=find(hquery);
     
     
完成,有兴趣的网又可以据此跳到 find 中看看具体执行情况,如果这样相信你会有更进一步得了解。还是那句话,这个解决方案也有不足的地方,如果你有更好的意见或方法,请和我联系。

 

posted on 2006-05-03 20:03 feingto 阅读(418) 评论(0)  编辑  收藏 所属分类: Java Web


只有注册用户登录后才能发表评论。


网站导航: