Hibernate分页查询经典范例总结 [转]

Hibernate分页查询经典实例总结 [转]
Hibernate分页查询经典实例总结

通常使用的Hibernate通常是三种:hql查询,QBC查询和QBE查询:
1、QBE(Qurey By Example)检索方式
QBE是最简单的,但是功能也是最弱的,QBE的功能不是特别强大,仅在某些场合下有用。一个典型的使用场合就是在查询窗口中让用户输入一系列的 查询条件,然后返回匹配的对象。QBE只支持=和like比较运算符,无法不大区间值,及其或的匹配。在这种情况下,还是采用HQL检索方式或QBC检索 方式。

    /**

        * @function 根据传递过来的Object,分页显示在数据库中与其匹配的记录

        * @param pageNo

        *            当前页数

        * @param pageSize

        *            每页显示的记录数

        * @param object

        *            将查询条件封装为Object

        * @return 将查询结果封装为Pager返回

        */

       public Pager findPageByExample(int pageNo, int pageSize, Object object)

       {

              Pager pager = null;

              try

              {

                     Criteria criteria = this.getSession().createCriteria(

                                   Class.forName(this.getEntity()));

 

                     if (object != null)

                     {

                            criteria.add(Example.create(object).enableLike());

                     }

 

                     // 获取根据条件分页查询的总行数

                     int rowCount = (Integer) criteria.setProjection(

                                   Projections.rowCount()).uniqueResult();

                     criteria.setProjection(null);

 

                     criteria.setFirstResult((pageNo - 1) * pageSize);

                     criteria.setMaxResults(pageSize);

 

                     List result = criteria.list();

 

                     pager = new Pager(pageSize, pageNo, rowCount, result);

 

              } catch (RuntimeException re)

              {

                     throw re;

              } finally

              {

                     return pager;

              }

 

       }


注意代码的第20行,即criteria.add(Example.create(object).enableLike());这一行,需将Example.create(object)调用.enableLike()方法,不然不能模糊查询。
在BO层将需要模糊查询的列用"%%"串起来,不然仍然和"="一样。
BO层代码:

/**

        * @function 将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录

        * @param pageNo

        *            当前的页码

        * @param pageSize

        *            每页显示的记录数

        * @param mendName

        *            抢修人员的名称

        * @param specialty

        *            抢修人员的工种

        * @param post

        *            抢修人员的职称

        * @return 将符合条件的记录数以及页码信息封装成PagerBean返回

        */

       public Pager getInfoByQuery(int pageNo, int pageSize, String mendName,

                     String specialty, String post)

       {

 

              EicMend eicMend = new EicMend();

              if (mendName != null && mendName.length() > 0)

              {

                     eicMend.setMendname("%" + mendName + "%");

              }

              if (specialty != null && specialty.length() > 0)

              {

                     eicMend.setSpecialty(specialty);

              }

              if (post != null && post.length() > 0)

              {

                     eicMend.setPost(post);

              }

 

              Pager pager = erpManagerDao

                            .findPageByExample(pageNo, pageSize, eicMend);

              return pager;

       }

执行SQL语句如下:

Hibernate: SQL代码
select count(*) as y0_ from YJZX.EIC_MEND this_ where

(this_.MENDNAME like ? and this_.POST like ?)







Hibernate: SQL代码
select * from ( select this_.MENDID as MENDID23_0_, ……

this_.EXPERTREMARK as EXPERTR28_23_0_ from YJZX.EIC_MEND this_ where

(this_.MENDNAME like ? and this_.POST like ?) ) where rownum <= ?



所以只需将需模糊查询的列用“%%”链接即可。

2、QBC(Qurey By Criteria)检索方式
       采用HQL检索方式时,在应用程序中需要定义基于字符串形式的HQL查询语句。QBC API提供了检索对象的另一种方式,它主要由Criteria接口、Criterion接口和Restrictions接口组成,它支持在运行时动态生成 查询语句。比较常见的是两种传参方式:一种是用map传参,另一种是用Criterion…不定参数传参。
Map传参方式范例如下:
DAO层:

     Java代码
/**

	        * @function 分页显示符合所有的记录数,将查询结果封装为Pager

	        * @param pageNo

	        *            当前页数

	        * @param pageSize

	        *            每页显示的条数

	        * @param map

	        *            将查询条件封装为map

	        * @return 查询结果Pager

	        */

	       public Pager findPageByCriteria(int pageNo, int pageSize, Map map)

	       {

	              Pager pager = null;

	              try

	              {

	                     Criteria criteria = this.getSession().createCriteria(

	                                   Class.forName(this.getEntity()));

	 

	                     if (map != null)

	                     {

	                            Set<string> keys = map.keySet();                              
	                           
	                            for (String key : keys){                                     
	                           
	                            	criteria.add(Restrictions.like(key, map.get(key)));                              
	                          
	                            }                      
	                     }                          
	                     // 获取根据条件分页查询的总行数                       
	                     int rowCount = (Integer) criteria.setProjection(                                     
	                    		 Projections.rowCount()).uniqueResult();                       
	                     
	                     criteria.setProjection(null);                          
	                     
	                     criteria.setFirstResult((pageNo - 1) * pageSize);                       
	                     
	                     criteria.setMaxResults(pageSize);                          
	                     
	                     List result = criteria.list();                          
	                     
	                     pager = new Pager(pageSize, pageNo, rowCount, result);                   
	                     
	              } catch (RuntimeException re)                
	              {                       
	            	
	            	  throw re;                
	            
	              } finally{                       
	            	
	            	  return pager;                
	              }   
	              
	         }

Map传参方式对应BO层代码:

      Java代码
/**

        * @function 将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录

        * @param pageNo

        *            当前的页码

        * @param pageSize

        *            每页显示的记录数

        * @param mendName

        *            抢修人员的名称

        * @param specialty

        *            抢修人员的工种

        * @param post

        *            抢修人员的职称

        * @return 将符合条件的记录数以及页码信息封装成PagerBean返回

        */

       public Pager getInfoByQuery2(int pageNo, int pageSize, String mendName,

                     String specialty, String post)

       {

 

              Map map = new HashMap();

 

              if (mendName != null && mendName.length() > 0)

              {

                     map.put("mendname", "%" + mendName + "%");

              }

              if (specialty != null && specialty.length() > 0)

              {

                     map.put("specialty", specialty);

              }

              if (post != null && post.length() > 0)

              {

                     map.put("post", post);

              }

 

              Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize, map);

              return pager;

       }


第二种方式:Criterion…不定参数传参方式。其代码如下所示:
DAO层代码:

     Java代码
/**

        * @function 分页显示符合所有的记录数,将查询结果封装为Pager

        * @param pageNo

        *            当前页数

        * @param pageSize

        *            每页显示的条数

        * @param criterions

        *            不定参数Criterion

        * @return 查询结果Pager

        */

       public Pager findPageByCriteria(int pageNo, int pageSize,

                     Criterion... criterions)

       {

              Pager pager = null;

              try

              {

                     Criteria criteria = this.getSession().createCriteria(

                                   Class.forName(this.getEntity()));

                     if (criterions != null)

                     {

                            for (Criterion criterion : criterions)

                            {

                                   if (criterion != null)

                                   {

                                          criteria.add(criterion);

                                   }

 

                            }

                     }

 

                     // 获取根据条件分页查询的总行数

                     int rowCount = (Integer) criteria.setProjection(

                                   Projections.rowCount()).uniqueResult();

                     criteria.setProjection(null);

 

                     criteria.setFirstResult((pageNo - 1) * pageSize);

                     criteria.setMaxResults(pageSize);

 

                     List result = criteria.list();

 

                     pager = new Pager(pageSize, pageNo, rowCount, result);

 

              } catch (RuntimeException re)

              {

                     throw re;

              } finally

              {

                     return pager;

              }

 

       }



Criterion…不定参数传参方式对应BO层代码:


Java代码
/**

        * @function 将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录

        * @param pageNo

        *            当前的页码

        * @param pageSize

        *            每页显示的记录数

        * @param mendName

        *            抢修人员的名称

        * @param specialty

        *            抢修人员的工种

        * @param post

        *            抢修人员的职称

        * @return 将符合条件的记录数以及页码信息封装成PagerBean返回

        */

       public Pager getInfoByQuery3(int pageNo, int pageSize, String mendName,

                     String specialty, String post)

       {

              Criterion criterion1 = null, criterion2 = null, criterion3 = null;

              if (mendName != null && mendName.length() > 0)

              {

                     criterion1 = Restrictions.ilike("mendname", mendName,

                                   MatchMode.ANYWHERE);

              }

 

              if (specialty != null && specialty.length() > 0)

              {

                     criterion2 = Restrictions.ilike("specialty", specialty,

                                   MatchMode.EXACT);

              }

 

              if (post != null && post.length() > 0)

              {

                     criterion3 = Restrictions.ilike("post", post, MatchMode.EXACT);

              }

 

              Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize,

                            criterion1, criterion2, criterion3);

 

              return pager;

       }





3、HQL检索方式



HQL(Hibernate Query Language)是面向对象的查询语言,它和SQL查询语言有些相识。在Hibernate提供的各种检索方式中,HQL是使用最广的一种检索方式。

使用Query接口分页查询DAO代码:


     Java代码
/**

        * @function 分页显示符合所有的记录数,将查询结果封装为Pager

        * @param pageNo

        *            当前页数

        * @param pageSize

        *            每页显示的条数

        * @param instance

        *            将查询条件封装为专家Bean

        * @return 查询结果Pager

        */

       public List<object> findPageByQuery(int pageNo, int pageSize, String hql,                       Map map)         {                List<object> result = null;                try                {                       Query query = this.getSession().createQuery(hql);                          Iterator it = map.keySet().iterator();                       while (it.hasNext())                       {                              Object key = it.next();                              query.setParameter(key.toString(), map.get(key));                       }                          query.setFirstResult((pageNo - 1) * pageSize);                       query.setMaxResults(pageSize);                          result = query.list();                   } catch (RuntimeException re)                {                       throw re;                }                return result;         }




查询所有记录数的DAO代码:

     Java代码
/**

        * @function 根据查询条件查询记录数的个数

        * @param hql

        *            hql查询语句

        * @param map

        *            用map封装查询条件

        * @return 数据库中满足查询条件的数据的条数

        */

       public int getTotalCount(String hql, Map map)

       {

              try

              {

                     Query query = this.getSession().createQuery(hql);

 

                     Iterator it = map.keySet().iterator();

                     while (it.hasNext())

                     {

                            Object key = it.next();

                            query.setParameter(key.toString(), map.get(key));

                     }

 

                     Integer i = (Integer) query.list().get(0);

                     return i;

              } catch (RuntimeException re)

              {

                     throw re;

              }

 

       }



BO层代码:

      Java代码
/**

        * @function 将传递过来的参数封装成专家Bean,分页查询符合条件的记录

        * @param pageNo

        *            当前的页码

        * @param pageSize

        *            每页显示的记录数

        * @param expertName

        *            专家的名称

        * @param expertSpecialty

        *            专家的专业类别

        * @param post

        *            专家的行政职位

        * @return 将符合条件的记录数以及页码信息封装成PagerBean返回

        */

       public Pager getInfoByQuery(int pageNo, int pageSize, String expertName,

                     String expertSpecialty, String post)

       {

              StringBuffer hql = new StringBuffer();

              hql.append("select count(expertid) from EicExpert where 1=1 ");

 

              Map map = new HashMap();

 

              if (expertName != null && expertName.length() > 0)

              {

                     map.put("expertname", "%" + expertName + "%");

                     hql.append("and expertname like :expertname ");

              }

              if (expertSpecialty != null && expertSpecialty.length() > 0)

              {

                     map.put("expertspecialty", expertSpecialty);

                     hql.append("and expertspecialty like :expertspecialty ");

              }

              if (post != null && post.length() > 0)

              {

                     map.put("post", post);

                     hql.append("and post like :post ");

              }

 

              String queryHql = hql.substring(22);

              List result = erpManagerDao.findPageByQuery(pageNo, pageSize,

                            queryHql, map);

              int rowCount = erpManagerDao.getTotalCount(hql.toString(), map);

 

              Pager pager = new Pager(pageSize, pageNo, rowCount, result);

              return pager;

       }

注:Pager类是我封装的一个分页类,包含 每页显示记录数,当前页,总记录数,每页显示数据的集合。因无关紧要,没有贴出来。另外我不知道Query接口有没有类似于Criteria那样可以直接 在分页查询记录的同时查询出总记录条数,知道的大虾麻烦告诉下哈。在BO里设置不定参数的时候感觉也不太好,不知道大虾们可有比较好的办法。
原文:http://www.sunxin.org/forum/thread/22927.html