ITPub博客

首页 > 数据库 > 数据库开发技术 > Hibernate综合查询解决方案 (转)

Hibernate综合查询解决方案 (转)

原创 数据库开发技术 作者:amyz 时间:2007-11-26 16:36:52 0 删除 编辑
Hibernate综合查询解决方案 (转)[@more@]

hibernate查询解决方案

  这两个星期以来,我把原来用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;
 
 /**
  *
  *

Title:定义一个sql语句的条件参数类


  *

Description: 可以使用有序的参数集合传送给sql/hql语句


  *

Copyright: Copyright (c) 2003


  *

Company: ifreeway


  * @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;
 
 /**
  *
  *

Title: 参数集合类


  *

Description: 封装sql/hql的参数到该集合类,便于处理和传递


  *

Copyright: Copyright (c) 2003


  *

Company: ifreeway


  * @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;
 
 
 /**
  *
  *

Title: HQL的语句封装类


  *

Description: 该对象封装HQL的查询语句,参数集合,排序参数,分组参数,单页起始地址 


  *

Copyright: Copyright (c) 2003


  *

Company:ifreeway


  * @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中看看具体执行情况,如果这样相信你会有更进一步得了解。还是那句话,这个解决方案也有不足的地方,如果你有更好的意见或方法,请和我联系。
 
  Jplateau


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752019/viewspace-984960/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    3984
  • 访问量
    7334718