关于使用Hibernate实现通用性分页功能的问题
1).在结合Spring时,在DAO层通过使用HibernatTemplate已经封装session的操作。如果在项目中仅仅使用Hibernate框架的话,那么在DAO层对每一个PO对象总是需要对Sesson进行open和close的操作。这样岂不是很会影响性能?请问,有没有什么方法可以改进?
2).关于使用Hibernate进行分页,能不能使用一个通用性的分页功能!这样就可以针对每一个PO对象进行相应的分页查询!!
[解决办法]
1、每个session代表一个会话,比作一次连接,每次的open和close是保证事务的完整性
2、使用通用性分页是在你用session操作时,既然你与spring结合使用,大多数情况下我们会用spring提供的HibernateTemplate来操作,这时你使用什么setFirstResult会有些麻烦
[解决办法]
个人认为1楼大哥说的不错
1.如果对Sesson不进行open和close的操作,那么容易将数据库连接池的资源耗尽,导致对数据库的操作失败。
2.同意一楼意见。
[解决办法]
这是我经常 用的分页功能通用工具类(如果你不使用struts,就得手动的把pageResult对象放入request)
- Java code
public class CommonDAOHibImpl extends HibernateDaoSupport implements CommonDAO { /** * 传一个hql语句过来,把结束存进pageResult */ public void listByPage(String hql, PageResult pageResult) { if (null==hql || pageResult== null ){ return ; } Query query = this.getSession().createQuery(hql); query.setFirstResult(pageResult.getFirstRec()); query.setMaxResults(pageResult.getPageSize()); List ret = query.list(); pageResult.setList(ret); String queryString = ""; if (hql.toUpperCase().indexOf("SELECT") != -1) { int i = query.getQueryString().toUpperCase().indexOf("FROM"); queryString = "Select count(*) " + hql.substring(i,hql.length()); } else { queryString = "Select count(*) " + hql; } // 去掉ORDER BY 的部分 int j = queryString.toUpperCase().lastIndexOf("ORDER"); if (j!=-1){ queryString = queryString.substring(0, j); } Query cquery = this.getSession().createQuery(queryString); cquery.setCacheable(true); int recTotal = ((Integer)cquery.iterate().next()).intValue(); pageResult.setRecTotal(recTotal); }}
[解决办法]
4楼的请问你用的是什么技术。hibernate?
public class CommonDAOHibImpl extends HibernateDaoSupport implements CommonDAO
继承HibernateDaoSupport类有什么作用啊?CommonDAO接口是不是定义的listByPage(String hql, PageResult pageResult)方法啊?
query.setFirstResult(pageResult.getFirstRec());
query.setMaxResults(pageResult.getPageSize());
这两句是什么意思 啊?
Query cquery = this.getSession().createQuery(queryString);这个得到的是什么啊?
cquery.setCacheable(true);什么意思啊?
int recTotal = ((Integer)cquery.iterate().next()).intValue(); 什么意思啊?
FormBean myForm = (FormBean) form;
这句话是不是写错了啊?
应该是BaseForm myForm =new BaseForm();
[解决办法]
自己感觉四楼代码非常好,重用性很高!不知道为什么五楼这样说,对他是否理解认真看待此贴对hibernate的理解感觉到怀疑!四楼的这段可以称得上是最优雅的代码!
[解决办法]
[解决办法]
用HibernateTemplate来操来处理吧,你不用自己管理session的open和close,如果光是分页查询也不用管理事物,HibernateTemplate提供了很多接口让你实现,只需要注入你的datasource就行啦
[解决办法]
高效程序通用分页最小功能集合:{动态sql生成功能,环境上下文存储区,连接管理功能}
高效DB通用分页最小功能集合:{动态sql生成功能,数据字典功能,通用接口标识调用功能}
------解决方案--------------------
session是轻量级的,允许随用随建,session的open和close,未必就意味着connection的关闭和链接。
建议使用bbcp管理connection
[解决办法]
如果,你只用Hibernate,参考org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter等(用Hibernate也会有类似的一个Filter)
其实,Spring会有一个Filter,当一个Request过来时,会打开一个Session,当Servlet处理结束时,这个Filter又可以把Hibernate的Session关闭。
你只需要造这个类似的Filter即可
至于分页,大如上面那些朋友写的。
不过,我很烦不停的写这些,自己写了个东西,把hql放在配置文件里,类似如
<page id="queryServiceGroup1" maxRecords="1" maxIndexPages="2">
<sql><![CDATA[
select (selct * from abc) from Entity where id=:id and name like :name and ?1 and 0=1
]]>
</sql>
<reps id="1" default="a=b">
<rep test="${id=='20'}"><![CDATA[abc${name}]]></rep>
<rep test="${id=='1'}"><![CDATA[b=c]]></rep>
</reps>
</page>
[解决办法]
Hibernate配合连接池使用,不会有什么影响使用的的性能问题的,Hibernate自己实现了很多缓存机制,除非进行海量数据操作,Hibernate配置好了,和JDBC效能不相上下。而分页,每次只会取出少量数据而已。