Hibernate分页查询小结

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

Java代码  

  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层代码:

Java代码  

  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语句如下:

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 <= ?

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

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

Java代码  

  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层代码:

Java代码  

  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层代码:

Java代码  

  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层代码:

Java代码  

  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代码:

Java代码  

  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代码:

Java代码  

  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层代码:

Java代码  

  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. if (expertName != null && expertName.length() > 0)
  22. {
  23. map.put("expertname", "%" + expertName + "%");
  24. hql.append("and expertname like :expertname ");
  25. }
  26. if (expertSpecialty != null && expertSpecialty.length() > 0)
  27. {
  28. map.put("expertspecialty", expertSpecialty);
  29. hql.append("and expertspecialty like :expertspecialty ");
  30. }
  31. if (post != null && post.length() > 0)
  32. {
  33. map.put("post", post);
  34. hql.append("and post like :post ");
  35. }
  36. String queryHql = hql.substring(22);
  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. }

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

时间: 2024-12-18 01:13:39

Hibernate分页查询小结的相关文章

Hibernate 分页 查询

昨天的作业  分页: 主要的代码块:(明天实现分页的封装) 1 package com.cy.beans; 2 3 import java.util.List; 4 5 /** 6 * 定义一个分页对象 7 * @author acer 8 * 9 */ 10 public class Pager { 11 12 private int page;//当前页码 13 private int pageTotal;//总页码 14 private int rowsTotal;//总条数 15 pri

hibernate分页查询的各种方法

统计总数: public Integer countAll1() { String hql = "select count(*) from News as news"; List list = getHibernateTemplate().find(hql); return list.get(0).hashCode(); } public Integer countAll2() { Criteria criteria = this.getSession().createCriteria

hibernate分页查询的实现

在mysql中新建数据好USER表,字段有3个,分别是id.username.password,贴上脚本仅供参考 create table `ding`.`user`(         `id` int default '' not null,        `username` varchar(30),        `password` varchar(30),         primary key (`id`)     ); 切换到数据库透视图,新建一个mysql连接(这里就不再多说了)

Hibernate分页查询报错

不知道什么原因,就是这里报错的 原文地址:https://www.cnblogs.com/feifeicui/p/8735182.html

Hibernate分页功能数据重复问题

今天遇到一个很憋屈的问题那就是hibernate分页查询中出现重复数据,本来一直没有在意,以为是数据问题,但是一查程序和数据都没有问题,继续深入查看,找到问题了就是order By 时出的问题,唉.... oracle中的分页机制就是通过rownum函数来实现的,rownum顺序号的生成是排序后生成的,例如:select * from web_user where  rownum > 0 and rownum <= 10 order by name 这个排序中使用了name字段作为排序,但是数

[原创]java WEB学习笔记90:Hibernate学习之路-- -HQL检索方式,分页查询,命名查询语句,投影查询,报表查询

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Hibernate支持类中的分页查询的实现

Hibernate支持类的实现 package com.myHibernateDao; import java.sql.SQLException; import java.util.List; import javax.annotation.Resource; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate

hibernate 中的query的分页查询

//方法描述:根据会员名称和页容量分页查询代理人 public List<HbUser> findUserByPage(int page,int pageSize, String userName)   throws Exception {  Session session = sessionFactory.getCurrentSession();  StringBuffer hql = new StringBuffer("from HbUser where isDelete = 0

Java_Web三大框架之Hibernate+jsp+HQL分页查询

分页查询无处不在.使用Hibernate+jsp+HQL进行分页查询. 第一步:编写房屋实体类和House.hbm.xml映射. /* * 房屋实体类 */ public class House { private int id;//房屋id private HouseType type;//房屋类型 private Users2 user;//用户 private Street street;//街道 private String title;//标题 private String descr