Hibernate分页查询小结

时间:2024-01-01 23:08:51

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

  1. /**
  2. * @function 根据传递过来的Object,分页显示在数据库中与其匹配的记录
  3. * @param pageNo
  4. *            当前页数
  5. * @param pageSize
  6. *            每页显示的记录数
  7. * @param object
  8. *            将查询条件封装为Object
  9. * @return 将查询结果封装为Pager返回
  10. */
  11. public Pager findPageByExample(int pageNo, int pageSize, Object object)
  12. {
  13. Pager pager = null;
  14. try
  15. {
  16. Criteria criteria = this.getSession().createCriteria(
  17. Class.forName(this.getEntity()));
  18. if (object != null)
  19. {
  20. criteria.add(Example.create(object).enableLike());
  21. }
  22. // 获取根据条件分页查询的总行数
  23. int rowCount = (Integer) criteria.setProjection(
  24. Projections.rowCount()).uniqueResult();
  25. criteria.setProjection(null);
  26. ) * pageSize);
  27. criteria.setMaxResults(pageSize);
  28. List result = criteria.list();
  29. pager = new Pager(pageSize, pageNo, rowCount, result);
  30. catch (RuntimeException re)
  31. {
  32. throw re;
  33. finally
  34. {
  35. return pager;
  36. }
  37. }
  1. /**
  2. * @function 根据传递过来的Object,分页显示在数据库中与其匹配的记录
  3. * @param pageNo
  4. *            当前页数
  5. * @param pageSize
  6. *            每页显示的记录数
  7. * @param object
  8. *            将查询条件封装为Object
  9. * @return 将查询结果封装为Pager返回
  10. */
  11. public Pager findPageByExample(int pageNo, int pageSize, Object object)
  12. {
  13. Pager pager = null;
  14. try
  15. {
  16. Criteria criteria = this.getSession().createCriteria(
  17. Class.forName(this.getEntity()));
  18. if (object != null)
  19. {
  20. criteria.add(Example.create(object).enableLike());
  21. }
  22. // 获取根据条件分页查询的总行数
  23. int rowCount = (Integer) criteria.setProjection(
  24. Projections.rowCount()).uniqueResult();
  25. criteria.setProjection(null);
  26. criteria.setFirstResult((pageNo - 1) * pageSize);
  27. criteria.setMaxResults(pageSize);
  28. List result = criteria.list();
  29. pager = new Pager(pageSize, pageNo, rowCount, result);
  30. } catch (RuntimeException re)
  31. {
  32. throw re;
  33. } finally
  34. {
  35. return pager;
  36. }
  37. }

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

  1. /**
  2. * @function 将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
  3. * @param pageNo
  4. *            当前的页码
  5. * @param pageSize
  6. *            每页显示的记录数
  7. * @param mendName
  8. *            抢修人员的名称
  9. * @param specialty
  10. *            抢修人员的工种
  11. * @param post
  12. *            抢修人员的职称
  13. * @return 将符合条件的记录数以及页码信息封装成PagerBean返回
  14. */
  15. public Pager getInfoByQuery(int pageNo, int pageSize, String mendName,
  16. String specialty, String post)
  17. {
  18. EicMend eicMend = new EicMend();
  19. )
  20. {
  21. eicMend.setMendname("%" + mendName + "%");
  22. }
  23. )
  24. {
  25. eicMend.setSpecialty(specialty);
  26. }
  27. )
  28. {
  29. eicMend.setPost(post);
  30. }
  31. Pager pager = erpManagerDao
  32. .findPageByExample(pageNo, pageSize, eicMend);
  33. return pager;
  34. }
  1. /**
  2. * @function 将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
  3. * @param pageNo
  4. *            当前的页码
  5. * @param pageSize
  6. *            每页显示的记录数
  7. * @param mendName
  8. *            抢修人员的名称
  9. * @param specialty
  10. *            抢修人员的工种
  11. * @param post
  12. *            抢修人员的职称
  13. * @return 将符合条件的记录数以及页码信息封装成PagerBean返回
  14. */
  15. public Pager getInfoByQuery(int pageNo, int pageSize, String mendName,
  16. String specialty, String post)
  17. {
  18. EicMend eicMend = new EicMend();
  19. if (mendName != null && mendName.length() > 0)
  20. {
  21. eicMend.setMendname("%" + mendName + "%");
  22. }
  23. if (specialty != null && specialty.length() > 0)
  24. {
  25. eicMend.setSpecialty(specialty);
  26. }
  27. if (post != null && post.length() > 0)
  28. {
  29. eicMend.setPost(post);
  30. }
  31. Pager pager = erpManagerDao
  32. .findPageByExample(pageNo, pageSize, eicMend);
  33. return pager;
  34. }

执行SQL语句如下:

  1. Hibernate: select count(*) as y0_ from YJZX.EIC_MEND this_ where
  2. (this_.MENDNAME like ? and this_.POST like ?)
  3. Hibernate: select * from ( select this_.MENDID as MENDID23_0_, ……
  4. this_.EXPERTREMARK as EXPERTR28_23_0_ from YJZX.EIC_MEND this_ where
  5. (this_.MENDNAME like ? and this_.POST like ?) ) where rownum <= ?
  1. Hibernate: select count(*) as y0_ from YJZX.EIC_MEND this_ where
  2. (this_.MENDNAME like ? and this_.POST like ?)
  3. Hibernate: select * from ( select this_.MENDID as MENDID23_0_, ……
  4. this_.EXPERTREMARK as EXPERTR28_23_0_ from YJZX.EIC_MEND this_ where
  5. (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层:

  1. /**
  2. * @function 分页显示符合所有的记录数,将查询结果封装为Pager
  3. * @param pageNo
  4. *            当前页数
  5. * @param pageSize
  6. *            每页显示的条数
  7. * @param map
  8. *            将查询条件封装为map
  9. * @return 查询结果Pager
  10. */
  11. public Pager findPageByCriteria(int pageNo, int pageSize, Map map)
  12. {
  13. Pager pager = null;
  14. try
  15. {
  16. Criteria criteria = this.getSession().createCriteria(
  17. Class.forName(this.getEntity()));
  18. if (map != null)
  19. {
  20. Set<String> keys = map.keySet();
  21. for (String key : keys)
  22. {
  23. criteria.add(Restrictions.like(key, map.get(key)));
  24. }
  25. }
  26. // 获取根据条件分页查询的总行数
  27. int rowCount = (Integer) criteria.setProjection(
  28. Projections.rowCount()).uniqueResult();
  29. criteria.setProjection(null);
  30. ) * pageSize);
  31. criteria.setMaxResults(pageSize);
  32. List result = criteria.list();
  33. pager = new Pager(pageSize, pageNo, rowCount, result);
  34. catch (RuntimeException re)
  35. {
  36. throw re;
  37. finally
  38. {
  39. return pager;
  40. }
  41. }
  1. /**
  2. * @function 分页显示符合所有的记录数,将查询结果封装为Pager
  3. * @param pageNo
  4. *            当前页数
  5. * @param pageSize
  6. *            每页显示的条数
  7. * @param map
  8. *            将查询条件封装为map
  9. * @return 查询结果Pager
  10. */
  11. public Pager findPageByCriteria(int pageNo, int pageSize, Map map)
  12. {
  13. Pager pager = null;
  14. try
  15. {
  16. Criteria criteria = this.getSession().createCriteria(
  17. Class.forName(this.getEntity()));
  18. if (map != null)
  19. {
  20. Set<String> keys = map.keySet();
  21. for (String key : keys)
  22. {
  23. criteria.add(Restrictions.like(key, map.get(key)));
  24. }
  25. }
  26. // 获取根据条件分页查询的总行数
  27. int rowCount = (Integer) criteria.setProjection(
  28. Projections.rowCount()).uniqueResult();
  29. criteria.setProjection(null);
  30. criteria.setFirstResult((pageNo - 1) * pageSize);
  31. criteria.setMaxResults(pageSize);
  32. List result = criteria.list();
  33. pager = new Pager(pageSize, pageNo, rowCount, result);
  34. } catch (RuntimeException re)
  35. {
  36. throw re;
  37. } finally
  38. {
  39. return pager;
  40. }
  41. }

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

  1. /**
  2. * @function 将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
  3. * @param pageNo
  4. *            当前的页码
  5. * @param pageSize
  6. *            每页显示的记录数
  7. * @param mendName
  8. *            抢修人员的名称
  9. * @param specialty
  10. *            抢修人员的工种
  11. * @param post
  12. *            抢修人员的职称
  13. * @return 将符合条件的记录数以及页码信息封装成PagerBean返回
  14. */
  15. public Pager getInfoByQuery2(int pageNo, int pageSize, String mendName,
  16. String specialty, String post)
  17. {
  18. Map map = new HashMap();
  19. )
  20. {
  21. map.put("mendname", "%" + mendName + "%");
  22. }
  23. )
  24. {
  25. map.put("specialty", specialty);
  26. }
  27. )
  28. {
  29. map.put("post", post);
  30. }
  31. Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize, map);
  32. return pager;
  33. }
  1. /**
  2. * @function 将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
  3. * @param pageNo
  4. *            当前的页码
  5. * @param pageSize
  6. *            每页显示的记录数
  7. * @param mendName
  8. *            抢修人员的名称
  9. * @param specialty
  10. *            抢修人员的工种
  11. * @param post
  12. *            抢修人员的职称
  13. * @return 将符合条件的记录数以及页码信息封装成PagerBean返回
  14. */
  15. public Pager getInfoByQuery2(int pageNo, int pageSize, String mendName,
  16. String specialty, String post)
  17. {
  18. Map map = new HashMap();
  19. if (mendName != null && mendName.length() > 0)
  20. {
  21. map.put("mendname", "%" + mendName + "%");
  22. }
  23. if (specialty != null && specialty.length() > 0)
  24. {
  25. map.put("specialty", specialty);
  26. }
  27. if (post != null && post.length() > 0)
  28. {
  29. map.put("post", post);
  30. }
  31. Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize, map);
  32. return pager;
  33. }

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

  1. /**
  2. * @function 分页显示符合所有的记录数,将查询结果封装为Pager
  3. * @param pageNo
  4. *            当前页数
  5. * @param pageSize
  6. *            每页显示的条数
  7. * @param criterions
  8. *            不定参数Criterion
  9. * @return 查询结果Pager
  10. */
  11. public Pager findPageByCriteria(int pageNo, int pageSize,
  12. Criterion... criterions)
  13. {
  14. Pager pager = null;
  15. try
  16. {
  17. Criteria criteria = this.getSession().createCriteria(
  18. Class.forName(this.getEntity()));
  19. if (criterions != null)
  20. {
  21. for (Criterion criterion : criterions)
  22. {
  23. if (criterion != null)
  24. {
  25. criteria.add(criterion);
  26. }
  27. }
  28. }
  29. // 获取根据条件分页查询的总行数
  30. int rowCount = (Integer) criteria.setProjection(
  31. Projections.rowCount()).uniqueResult();
  32. criteria.setProjection(null);
  33. ) * pageSize);
  34. criteria.setMaxResults(pageSize);
  35. List result = criteria.list();
  36. pager = new Pager(pageSize, pageNo, rowCount, result);
  37. catch (RuntimeException re)
  38. {
  39. throw re;
  40. finally
  41. {
  42. return pager;
  43. }
  44. }
  1. /**
  2. * @function 分页显示符合所有的记录数,将查询结果封装为Pager
  3. * @param pageNo
  4. *            当前页数
  5. * @param pageSize
  6. *            每页显示的条数
  7. * @param criterions
  8. *            不定参数Criterion
  9. * @return 查询结果Pager
  10. */
  11. public Pager findPageByCriteria(int pageNo, int pageSize,
  12. Criterion... criterions)
  13. {
  14. Pager pager = null;
  15. try
  16. {
  17. Criteria criteria = this.getSession().createCriteria(
  18. Class.forName(this.getEntity()));
  19. if (criterions != null)
  20. {
  21. for (Criterion criterion : criterions)
  22. {
  23. if (criterion != null)
  24. {
  25. criteria.add(criterion);
  26. }
  27. }
  28. }
  29. // 获取根据条件分页查询的总行数
  30. int rowCount = (Integer) criteria.setProjection(
  31. Projections.rowCount()).uniqueResult();
  32. criteria.setProjection(null);
  33. criteria.setFirstResult((pageNo - 1) * pageSize);
  34. criteria.setMaxResults(pageSize);
  35. List result = criteria.list();
  36. pager = new Pager(pageSize, pageNo, rowCount, result);
  37. } catch (RuntimeException re)
  38. {
  39. throw re;
  40. } finally
  41. {
  42. return pager;
  43. }
  44. }

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

  1. /**
  2. * @function 将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
  3. * @param pageNo
  4. *            当前的页码
  5. * @param pageSize
  6. *            每页显示的记录数
  7. * @param mendName
  8. *            抢修人员的名称
  9. * @param specialty
  10. *            抢修人员的工种
  11. * @param post
  12. *            抢修人员的职称
  13. * @return 将符合条件的记录数以及页码信息封装成PagerBean返回
  14. */
  15. public Pager getInfoByQuery3(int pageNo, int pageSize, String mendName,
  16. String specialty, String post)
  17. {
  18. Criterion criterion1 = null, criterion2 = null, criterion3 = null;
  19. )
  20. {
  21. criterion1 = Restrictions.ilike("mendname", mendName,
  22. MatchMode.ANYWHERE);
  23. }
  24. )
  25. {
  26. criterion2 = Restrictions.ilike("specialty", specialty,
  27. MatchMode.EXACT);
  28. }
  29. )
  30. {
  31. criterion3 = Restrictions.ilike("post", post, MatchMode.EXACT);
  32. }
  33. Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize,
  34. criterion1, criterion2, criterion3);
  35. return pager;
  36. }
  1. /**
  2. * @function 将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
  3. * @param pageNo
  4. *            当前的页码
  5. * @param pageSize
  6. *            每页显示的记录数
  7. * @param mendName
  8. *            抢修人员的名称
  9. * @param specialty
  10. *            抢修人员的工种
  11. * @param post
  12. *            抢修人员的职称
  13. * @return 将符合条件的记录数以及页码信息封装成PagerBean返回
  14. */
  15. public Pager getInfoByQuery3(int pageNo, int pageSize, String mendName,
  16. String specialty, String post)
  17. {
  18. Criterion criterion1 = null, criterion2 = null, criterion3 = null;
  19. if (mendName != null && mendName.length() > 0)
  20. {
  21. criterion1 = Restrictions.ilike("mendname", mendName,
  22. MatchMode.ANYWHERE);
  23. }
  24. if (specialty != null && specialty.length() > 0)
  25. {
  26. criterion2 = Restrictions.ilike("specialty", specialty,
  27. MatchMode.EXACT);
  28. }
  29. if (post != null && post.length() > 0)
  30. {
  31. criterion3 = Restrictions.ilike("post", post, MatchMode.EXACT);
  32. }
  33. Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize,
  34. criterion1, criterion2, criterion3);
  35. return pager;
  36. }

3、HQL检索方式

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

  1. /**
  2. * @function 分页显示符合所有的记录数,将查询结果封装为Pager
  3. * @param pageNo
  4. *            当前页数
  5. * @param pageSize
  6. *            每页显示的条数
  7. * @param instance
  8. *            将查询条件封装为专家Bean
  9. * @return 查询结果Pager
  10. */
  11. public List<Object> findPageByQuery(int pageNo, int pageSize, String hql,
  12. Map map)
  13. {
  14. List<Object> result = null;
  15. try
  16. {
  17. Query query = this.getSession().createQuery(hql);
  18. Iterator it = map.keySet().iterator();
  19. while (it.hasNext())
  20. {
  21. Object key = it.next();
  22. query.setParameter(key.toString(), map.get(key));
  23. }
  24. ) * pageSize);
  25. query.setMaxResults(pageSize);
  26. result = query.list();
  27. catch (RuntimeException re)
  28. {
  29. throw re;
  30. }
  31. return result;
  32. }
  1. /**
  2. * @function 分页显示符合所有的记录数,将查询结果封装为Pager
  3. * @param pageNo
  4. *            当前页数
  5. * @param pageSize
  6. *            每页显示的条数
  7. * @param instance
  8. *            将查询条件封装为专家Bean
  9. * @return 查询结果Pager
  10. */
  11. public List<Object> findPageByQuery(int pageNo, int pageSize, String hql,
  12. Map map)
  13. {
  14. List<Object> result = null;
  15. try
  16. {
  17. Query query = this.getSession().createQuery(hql);
  18. Iterator it = map.keySet().iterator();
  19. while (it.hasNext())
  20. {
  21. Object key = it.next();
  22. query.setParameter(key.toString(), map.get(key));
  23. }
  24. query.setFirstResult((pageNo - 1) * pageSize);
  25. query.setMaxResults(pageSize);
  26. result = query.list();
  27. } catch (RuntimeException re)
  28. {
  29. throw re;
  30. }
  31. return result;
  32. }

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

  1. /**
  2. * @function 根据查询条件查询记录数的个数
  3. * @param hql
  4. *            hql查询语句
  5. * @param map
  6. *            用map封装查询条件
  7. * @return 数据库中满足查询条件的数据的条数
  8. */
  9. public int getTotalCount(String hql, Map map)
  10. {
  11. try
  12. {
  13. Query query = this.getSession().createQuery(hql);
  14. Iterator it = map.keySet().iterator();
  15. while (it.hasNext())
  16. {
  17. Object key = it.next();
  18. query.setParameter(key.toString(), map.get(key));
  19. }
  20. );
  21. return i;
  22. catch (RuntimeException re)
  23. {
  24. throw re;
  25. }
  26. }
  1. /**
  2. * @function 根据查询条件查询记录数的个数
  3. * @param hql
  4. *            hql查询语句
  5. * @param map
  6. *            用map封装查询条件
  7. * @return 数据库中满足查询条件的数据的条数
  8. */
  9. public int getTotalCount(String hql, Map map)
  10. {
  11. try
  12. {
  13. Query query = this.getSession().createQuery(hql);
  14. Iterator it = map.keySet().iterator();
  15. while (it.hasNext())
  16. {
  17. Object key = it.next();
  18. query.setParameter(key.toString(), map.get(key));
  19. }
  20. Integer i = (Integer) query.list().get(0);
  21. return i;
  22. } catch (RuntimeException re)
  23. {
  24. throw re;
  25. }
  26. }

BO层代码:

    1. /**
    2. * @function 将传递过来的参数封装成专家Bean,分页查询符合条件的记录
    3. * @param pageNo
    4. *            当前的页码
    5. * @param pageSize
    6. *            每页显示的记录数
    7. * @param expertName
    8. *            专家的名称
    9. * @param expertSpecialty
    10. *            专家的专业类别
    11. * @param post
    12. *            专家的行政职位
    13. * @return 将符合条件的记录数以及页码信息封装成PagerBean返回
    14. */
    15. public Pager getInfoByQuery(int pageNo, int pageSize, String expertName,
    16. String expertSpecialty, String post)
    17. {
    18. StringBuffer hql = new StringBuffer();
    19. hql.append("select count(expertid) from EicExpert where 1=1 ");
    20. Map map = new HashMap();
    21. )
    22. {
    23. map.put("expertname", "%" + expertName + "%");
    24. hql.append("and expertname like :expertname ");
    25. }
    26. )
    27. {
    28. map.put("expertspecialty", expertSpecialty);
    29. hql.append("and expertspecialty like :expertspecialty ");
    30. }
    31. )
    32. {
    33. map.put("post", post);
    34. hql.append("and post like :post ");
    35. }
    36. );
    37. List result = erpManagerDao.findPageByQuery(pageNo, pageSize,
    38. queryHql, map);
    39. int rowCount = erpManagerDao.getTotalCount(hql.toString(), map);
    40. Pager pager = new Pager(pageSize, pageNo, rowCount, result);
    41. return pager;
    42. }