Hibernate查询解决方案

    技术2022-05-11  12

    这两个星期以来,我把原来用struts开发的一个测试工具改用struts+hibernate来实现,首先从心情上来,整个开发过程中始终保持愉快和平和,“原来开发可以这样愉快?”,再一点就是开发效率上高效了许多。       现在sun又加入jdocentral.com开始着手JDO2.0,想想看等它出台以后将是一个怎样激动人心得场面,让我们拭目以待。             用Hibernate来操纵持久数据非常简单,在这里一些简单的查询我会一笔带过,本文着重说明在综合查询兼有分页的时候我的一些经验,如果网友觉得我的方案还有不足的地方,也请和我讨论,我的email:plateau_t@sina.com.             第一部分: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); 


    最新回复(0)