Hibernate分页查询小结
通常使用的Hibernate通常是三种:hql查询,QBC查询和QBE查询:
1、QBE(QureyByExample)检索方式
QBE是最简单的,但是功能也是最弱的,QBE的功能不是特别强大,仅在某些场合下有用。一个典型的使用场合就是在查询窗口中让用户输入一系列的查询条件,然后返回匹配的对象。QBE只支持=和like比较运算符,无法不大区间值,及其或的匹配。在这种情况下,还是采用HQL检索方式或QBC检索方式。
Java代码
1./**
2.*@function根据传递过来的Object,分页显示在数据库中与其匹配的记录
3.*@parampageNo
4.*当前页数
5.*@parampageSize
6.*每页显示的记录数
7.*@paramobject
8.*将查询条件封装为Object
9.*@return将查询结果封装为Pager返回
10.*/
11.publicPagerfindPageByExample(intpageNo,intpageSize,Objectobject)
12.{
13.Pagerpager=null;
14.try
15.{
16.Criteriacriteria=this.getSession().createCriteria(
17.Class.forName(this.getEntity()));
18.
19.if(object!=null)
20.{
21.criteria.add(Example.create(object).enableLike());
22.}
23.
24.//获取根据条件分页查询的总行数
25.introwCount=(Integer)criteria.setProjection(
26.Projections.rowCount()).uniqueResult();
27.criteria.setProjection(null);
28.
29.criteria.setFirstResult((pageNo-1)*pageSize);
30.criteria.setMaxResults(pageSize);
31.
32.Listresult=criteria.list();
33.
34.pager=newPager(pageSize,pageNo,rowCount,result);
35.
36.}catch(RuntimeExceptionre)
37.{
38.throwre;
39.}finally
40.{
41.returnpager;
42.}
43.
44.}
/**
*@function根据传递过来的Object,分页显示在数据库中与其匹配的记录
*@parampageNo
*当前页数
*@parampageSize
*每页显示的记录数
*@paramobject
*将查询条件封装为Object
*@return将查询结果封装为Pager返回
*/
publicPagerfindPageByExample(intpageNo,intpageSize,Objectobject)
{
Pagerpager=null;
try
{
Criteriacriteria=this.getSession().createCriteria(
Class.forName(this.getEntity()));if (object != null)
{
criteria.add(Example.create(object).enableLike());
}// 获取根据条件分页查询的总行数
introwCount=(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)
{
throwre;
}finally
{
returnpager;
}}
注意代码的第20行,即criteria.add(Example.create(object).enableLike());这一行,需将Example.create(object)调用.enableLike()方法,不然不能模糊查询。
在BO层将需要模糊查询的列用"%%"串起来,不然仍然和"="一样。
BO层代码:
Java代码
1./**
2.*@function将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
3.*@parampageNo
4.*当前的页码
5.*@parampageSize
6.*每页显示的记录数
7.*@parammendName
8.*抢修人员的名称
9.*@paramspecialty
10.*抢修人员的工种
11.*@parampost
12.*抢修人员的职称
13.*@return将符合条件的记录数以及页码信息封装成PagerBean返回
14.*/
15.publicPagergetInfoByQuery(intpageNo,intpageSize,StringmendName,
16.Stringspecialty,Stringpost)
17.{
18.
19.EicMendeicMend=newEicMend();
20.if(mendName!=null&&mendName.length()>0)
21.{
22.eicMend.setMendname("%"+mendName+"%");
23.}
24.if(specialty!=null&&specialty.length()>0)
25.{
26.eicMend.setSpecialty(specialty);
27.}
28.if(post!=null&&post.length()>0)
29.{
30.eicMend.setPost(post);
31.}
32.
33.Pagerpager=erpManagerDao
34..findPageByExample(pageNo,pageSize,eicMend);
35.returnpager;
36.}
/**
*@function将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
*@parampageNo
*当前的页码
*@parampageSize
*每页显示的记录数
*@parammendName
*抢修人员的名称
*@paramspecialty
*抢修人员的工种
*@parampost
*抢修人员的职称
*@return将符合条件的记录数以及页码信息封装成PagerBean返回
*/
publicPagergetInfoByQuery(intpageNo,intpageSize,StringmendName,
Stringspecialty,Stringpost)
{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);
returnpager;
}执行SQL语句如下:
Sql代码
1.Hibernate:selectcount(*)asy0_fromYJZX.EIC_MENDthis_where
2.(this_.MENDNAMElike?andthis_.POSTlike?)
3.
4.Hibernate:select*from(selectthis_.MENDIDasMENDID23_0_,......
5.this_.EXPERTREMARKasEXPERTR28_23_0_fromYJZX.EIC_MENDthis_where
6.(this_.MENDNAMElike?andthis_.POSTlike?))whererownum<=?
Hibernate:selectcount(*)asy0_fromYJZX.EIC_MENDthis_where
(this_.MENDNAME like ? and this_.POST like ?)Hibernate: select * from ( select this_.MENDID as MENDID23_0_, ......
this_.EXPERTREMARKasEXPERTR28_23_0_fromYJZX.EIC_MENDthis_where
(this_.MENDNAME like ? and this_.POST like ?) ) where rownum <= ?所以只需将需模糊查询的列用"%%"链接即可。
2、QBC(Qurey By Criteria)检索方式
采用HQL检索方式时,在应用程序中需要定义基于字符串形式的HQL查询语句。QBCAPI提供了检索对象的另一种方式,它主要由Criteria接口、Criterion接口和Restrictions接口组成,它支持在运行时动态生成查询语句。比较常见的是两种传参方式:一种是用map传参,另一种是用Criterion...不定参数传参。
Map传参方式范例如下:
DAO层:
Java代码
1./**
2.*@function分页显示符合所有的记录数,将查询结果封装为Pager
3.*@parampageNo
4.*当前页数
5.*@parampageSize
6.*每页显示的条数
7.*@parammap
8.*将查询条件封装为map
9.*@return查询结果Pager
10.*/
11.publicPagerfindPageByCriteria(intpageNo,intpageSize,Mapmap)
12.{
13.Pagerpager=null;
14.try
15.{
16.Criteriacriteria=this.getSession().createCriteria(
17.Class.forName(this.getEntity()));
18.
19.if(map!=null)
20.{
21.Set<String>keys=map.keySet();
22.for(Stringkey:keys)
23.{
24.criteria.add(Restrictions.like(key,map.get(key)));
25.}
26.}
27.
28.//获取根据条件分页查询的总行数
29.introwCount=(Integer)criteria.setProjection(
30.Projections.rowCount()).uniqueResult();
31.criteria.setProjection(null);
32.
33.criteria.setFirstResult((pageNo-1)*pageSize);
34.criteria.setMaxResults(pageSize);
35.
36.Listresult=criteria.list();
37.
38.pager=newPager(pageSize,pageNo,rowCount,result);
39.
40.}catch(RuntimeExceptionre)
41.{
42.throwre;
43.}finally
44.{
45.returnpager;
46.}
47.
48.}
/**
*@function分页显示符合所有的记录数,将查询结果封装为Pager
*@parampageNo
*当前页数
*@parampageSize
*每页显示的条数
*@parammap
*将查询条件封装为map
*@return查询结果Pager
*/
publicPagerfindPageByCriteria(intpageNo,intpageSize,Mapmap)
{
Pagerpager=null;
try
{
Criteriacriteria=this.getSession().createCriteria(
Class.forName(this.getEntity()));if (map != null)
{
Set<String>keys=map.keySet();
for(Stringkey:keys)
{
criteria.add(Restrictions.like(key,map.get(key)));
}
}// 获取根据条件分页查询的总行数
introwCount=(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)
{
throwre;
}finally
{
returnpager;
}}
Map传参方式对应BO层代码:
Java代码
1./**
2.*@function将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
3.*@parampageNo
4.*当前的页码
5.*@parampageSize
6.*每页显示的记录数
7.*@parammendName
8.*抢修人员的名称
9.*@paramspecialty
10.*抢修人员的工种
11.*@parampost
12.*抢修人员的职称
13.*@return将符合条件的记录数以及页码信息封装成PagerBean返回
14.*/
15.publicPagergetInfoByQuery2(intpageNo,intpageSize,StringmendName,
16.Stringspecialty,Stringpost)
17.{
18.
19.Mapmap=newHashMap();
20.
21.if(mendName!=null&&mendName.length()>0)
22.{
23.map.put("mendname","%"+mendName+"%");
24.}
25.if(specialty!=null&&specialty.length()>0)
26.{
27.map.put("specialty",specialty);
28.}
29.if(post!=null&&post.length()>0)
30.{
31.map.put("post",post);
32.}
33.
34.Pagerpager=erpManagerDao.findPageByCriteria(pageNo,pageSize,map);
35.returnpager;
36.}
/**
*@function将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
*@parampageNo
*当前的页码
*@parampageSize
*每页显示的记录数
*@parammendName
*抢修人员的名称
*@paramspecialty
*抢修人员的工种
*@parampost
*抢修人员的职称
*@return将符合条件的记录数以及页码信息封装成PagerBean返回
*/
publicPagergetInfoByQuery2(intpageNo,intpageSize,StringmendName,
Stringspecialty,Stringpost)
{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);
returnpager;
}第二种方式:Criterion...不定参数传参方式。其代码如下所示:
DAO层代码:
Java代码
1./**
2.*@function分页显示符合所有的记录数,将查询结果封装为Pager
3.*@parampageNo
4.*当前页数
5.*@parampageSize
6.*每页显示的条数
7.*@paramcriterions
8.*不定参数Criterion
9.*@return查询结果Pager
10.*/
11.publicPagerfindPageByCriteria(intpageNo,intpageSize,
12.Criterion...criterions)
13.{
14.Pagerpager=null;
15.try
16.{
17.Criteriacriteria=this.getSession().createCriteria(
18.Class.forName(this.getEntity()));
19.if(criterions!=null)
20.{
21.for(Criterioncriterion:criterions)
22.{
23.if(criterion!=null)
24.{
25.criteria.add(criterion);
26.}
27.
28.}
29.}
30.
31.//获取根据条件分页查询的总行数
32.introwCount=(Integer)criteria.setProjection(
33.Projections.rowCount()).uniqueResult();
34.criteria.setProjection(null);
35.
36.criteria.setFirstResult((pageNo-1)*pageSize);
37.criteria.setMaxResults(pageSize);
38.
39.Listresult=criteria.list();
40.
41.pager=newPager(pageSize,pageNo,rowCount,result);
42.
43.}catch(RuntimeExceptionre)
44.{
45.throwre;
46.}finally
47.{
48.returnpager;
49.}
50.
51.}
/**
*@function分页显示符合所有的记录数,将查询结果封装为Pager
*@parampageNo
*当前页数
*@parampageSize
*每页显示的条数
*@paramcriterions
*不定参数Criterion
*@return查询结果Pager
*/
publicPagerfindPageByCriteria(intpageNo,intpageSize,
Criterion...criterions)
{
Pagerpager=null;
try
{
Criteriacriteria=this.getSession().createCriteria(
Class.forName(this.getEntity()));
if(criterions!=null)
{
for(Criterioncriterion:criterions)
{
if(criterion!=null)
{
criteria.add(criterion);
}} }
// 获取根据条件分页查询的总行数
introwCount=(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)
{
throwre;
}finally
{
returnpager;
}}
Criterion...不定参数传参方式对应BO层代码:
Java代码
1./**
2.*@function将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
3.*@parampageNo
4.*当前的页码
5.*@parampageSize
6.*每页显示的记录数
7.*@parammendName
8.*抢修人员的名称
9.*@paramspecialty
10.*抢修人员的工种
11.*@parampost
12.*抢修人员的职称
13.*@return将符合条件的记录数以及页码信息封装成PagerBean返回
14.*/
15.publicPagergetInfoByQuery3(intpageNo,intpageSize,StringmendName,
16.Stringspecialty,Stringpost)
17.{
18.Criterioncriterion1=null,criterion2=null,criterion3=null;
19.if(mendName!=null&&mendName.length()>0)
20.{
21.criterion1=Restrictions.ilike("mendname",mendName,
22.MatchMode.ANYWHERE);
23.}
24.
25.if(specialty!=null&&specialty.length()>0)
26.{
27.criterion2=Restrictions.ilike("specialty",specialty,
28.MatchMode.EXACT);
29.}
30.
31.if(post!=null&&post.length()>0)
32.{
33.criterion3=Restrictions.ilike("post",post,MatchMode.EXACT);
34.}
35.
36.Pagerpager=erpManagerDao.findPageByCriteria(pageNo,pageSize,
37.criterion1,criterion2,criterion3);
38.
39.returnpager;
40.}
/**
*@function将传递过来的参数封装成抢修人员Bean,分页查询符合条件的记录
*@parampageNo
*当前的页码
*@parampageSize
*每页显示的记录数
*@parammendName
*抢修人员的名称
*@paramspecialty
*抢修人员的工种
*@parampost
*抢修人员的职称
*@return将符合条件的记录数以及页码信息封装成PagerBean返回
*/
publicPagergetInfoByQuery3(intpageNo,intpageSize,StringmendName,
Stringspecialty,Stringpost)
{
Criterioncriterion1=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代码
1./**
2.*@function分页显示符合所有的记录数,将查询结果封装为Pager
3.*@parampageNo
4.*当前页数
5.*@parampageSize
6.*每页显示的条数
7.*@paraminstance
8.*将查询条件封装为专家Bean
9.*@return查询结果Pager
10.*/
11.publicList<Object>findPageByQuery(intpageNo,intpageSize,Stringhql,
12.Mapmap)
13.{
14.List<Object>result=null;
15.try
16.{
17.Queryquery=this.getSession().createQuery(hql);
18.
19.Iteratorit=map.keySet().iterator();
20.while(it.hasNext())
21.{
22.Objectkey=it.next();
23.query.setParameter(key.toString(),map.get(key));
24.}
25.
26.query.setFirstResult((pageNo-1)*pageSize);
27.query.setMaxResults(pageSize);
28.
29.result=query.list();
30.
31.}catch(RuntimeExceptionre)
32.{
33.throwre;
34.}
35.returnresult;
36.}
/**
*@function分页显示符合所有的记录数,将查询结果封装为Pager
*@parampageNo
*当前页数
*@parampageSize
*每页显示的条数
*@paraminstance
*将查询条件封装为专家Bean
*@return查询结果Pager
*/
publicList<Object>findPageByQuery(intpageNo,intpageSize,Stringhql,
Mapmap)
{
List<Object>result=null;
try
{
Query query = this.getSession().createQuery(hql);Iterator it = map.keySet().iterator();
while(it.hasNext())
{
Objectkey=it.next();
query.setParameter(key.toString(),map.get(key));
}query.setFirstResult((pageNo - 1) * pageSize); query.setMaxResults(pageSize);
result = query.list();
} catch (RuntimeException re)
{
throwre;
}
returnresult;
}查询所有记录数的DAO代码:
Java代码
1./**
2.*@function根据查询条件查询记录数的个数
3.*@paramhql
4.*hql查询语句
5.*@parammap
6.*用map封装查询条件
7.*@return数据库中满足查询条件的数据的条数
8.*/
9.publicintgetTotalCount(Stringhql,Mapmap)
10.{
11.try
12.{
13.Queryquery=this.getSession().createQuery(hql);
14.
15.Iteratorit=map.keySet().iterator();
16.while(it.hasNext())
17.{
18.Objectkey=it.next();
19.query.setParameter(key.toString(),map.get(key));
20.}
21.
22.Integeri=(Integer)query.list().get(0);
23.returni;
24.}catch(RuntimeExceptionre)
25.{
26.throwre;
27.}
28.
29.}
/**
*@function根据查询条件查询记录数的个数
*@paramhql
*hql查询语句
*@parammap
*用map封装查询条件
*@return数据库中满足查询条件的数据的条数
*/
publicintgetTotalCount(Stringhql,Mapmap)
{
try
{
Query query = this.getSession().createQuery(hql);Iterator it = map.keySet().iterator();
while(it.hasNext())
{
Objectkey=it.next();
query.setParameter(key.toString(),map.get(key));
}Integer i = (Integer) query.list().get(0);
returni;
}catch(RuntimeExceptionre)
{
throwre;
}}
BO层代码:
Java代码
1./**
2.*@function将传递过来的参数封装成专家Bean,分页查询符合条件的记录
3.*@parampageNo
4.*当前的页码
5.*@parampageSize
6.*每页显示的记录数
7.*@paramexpertName
8.*专家的名称
9.*@paramexpertSpecialty
10.*专家的专业类别
11.*@parampost
12.*专家的行政职位
13.*@return将符合条件的记录数以及页码信息封装成PagerBean返回
14.*/
15.publicPagergetInfoByQuery(intpageNo,intpageSize,StringexpertName,
16.StringexpertSpecialty,Stringpost)
17.{
18.StringBufferhql=newStringBuffer();
19.hql.append("selectcount(expertid)fromEicExpertwhere1=1");
20.
21.Mapmap=newHashMap();
22.
23.if(expertName!=null&&expertName.length()>0)
24.{
25.map.put("expertname","%"+expertName+"%");
26.hql.append("andexpertnamelike:expertname");
27.}
28.if(expertSpecialty!=null&&expertSpecialty.length()>0)
29.{
30.map.put("expertspecialty",expertSpecialty);
31.hql.append("andexpertspecialtylike:expertspecialty");
32.}
33.if(post!=null&&post.length()>0)
34.{
35.map.put("post",post);
36.hql.append("andpostlike:post");
37.}
38.
39.StringqueryHql=hql.substring(22);
40.Listresult=erpManagerDao.findPageByQuery(pageNo,pageSize,
41.queryHql,map);
42.introwCount=erpManagerDao.getTotalCount(hql.toString(),map);
43.
44.Pagerpager=newPager(pageSize,pageNo,rowCount,result);
45.returnpager;
46.}
/**
*@function将传递过来的参数封装成专家Bean,分页查询符合条件的记录
*@parampageNo
*当前的页码
*@parampageSize
*每页显示的记录数
*@paramexpertName
*专家的名称
*@paramexpertSpecialty
*专家的专业类别
*@parampost
*专家的行政职位
*@return将符合条件的记录数以及页码信息封装成PagerBean返回
*/
publicPagergetInfoByQuery(intpageNo,intpageSize,StringexpertName,
StringexpertSpecialty,Stringpost)
{
StringBufferhql=newStringBuffer();
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("andexpertnamelike:expertname");
}
if(expertSpecialty!=null&&expertSpecialty.length()>0)
{
map.put("expertspecialty",expertSpecialty);
hql.append("andexpertspecialtylike:expertspecialty");
}
if(post!=null&&post.length()>0)
{
map.put("post",post);
hql.append("andpostlike:post");
}String queryHql = hql.substring(22);
Listresult=erpManagerDao.findPageByQuery(pageNo,pageSize,
queryHql,map);
int rowCount = erpManagerDao.getTotalCount(hql.toString(), map);Pager pager = new Pager(pageSize, pageNo, rowCount, result);
returnpager;
}注:Pager类是我封装的一个分页类,包含 每页显示记录数,当前页,总记录数,每页显示数据的集合。因无关紧要,没有贴出来。另外我不知道Query接口有没有类似于Criteria那样可以直接在分页查询记录的同时查询出总记录条数,知道的大虾麻烦告诉下哈。在BO里设置不定参数的时候感觉也不太好,不知道大虾们可有比较好的办法。