浏览 3404 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-08
尤其是对于一些需要自定义对数据进行更改的操作时,Spring提供的update和save就远远无法满足复杂的业务需求了 此时,我们只能使用callback方法来回调,除此以外,Hibernate的分页查询功能也不能逃脱此列,只能使用callback方法来实现 于是我在架构项目的时候,写了两个callback方法以简化开发,减少冗余代码 一个是ExecuteCallback,用于执行更新和删除的 一个是PageCallback,用于执行hibernate分页的 这里就以PageCallback为例来讨论 public abstract class BaseCallback implements HibernateCallback { protected volatile String hql; public String getHql() { return hql; } public synchronized void setHql(String hql) { this.hql = hql; } } public class PageCallback extends BaseCallback { protected volatile int startRow; protected volatile int pageSize; public int getStartRow() { return startRow; } public synchronized void setStartRow(int startRow) { this.startRow = startRow; } public int getPageSize() { return pageSize; } public synchronized void setPageSize(int pageSize) { this.pageSize = pageSize; } public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(hql); query.setFirstResult(startRow); query.setMaxResults(pageSize); List list = query.list(); return list; } } 可以看到代码中我用到了volatile和synchronized 这是因为我发现这样设计,产生了并发的问题,线程不再安全,所以我才加上去的 不过加上去后,结果并不是非常满意,虽然并发问题被改善了,但是依然存在,只是降低了发生的频率而已 其实最安全的方法就是直接把callback的回调写在dao中,不过这实在太恐怖了。。我不敢想象这种情况 不知道spring在设计之初,是不是故意不封装callback进去的。。。现在都觉得这个问题开始让人很头大了,我想如果换成ibatis,应该是没有这样的问题的,毕竟灵活性比hibernate要强很多,不需要callback这一类问题 不知道大家在整合spring和hibernate的时候,是如何分页的?如果使用的是callback,是否也跟我一样遇到过这样的并发问题呢? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-04-08
用参数代替实例变量不就没有并发问题了?
|
|
返回顶楼 | |
发表时间:2009-04-08
daquan198163 写道 用参数代替实例变量不就没有并发问题了? 不行啊 Callback中的doInHibernate不允许传参数阿 要不然我也想这么做。。。。。 |
|
返回顶楼 | |
发表时间:2009-04-08
最后修改:2009-04-10
突然想到了一个思路
就是dao的父类中定义两个方法 protected List getPage(final String hql, final int startrow,final int pagesize) { return getHibernateTemplate().executeFind(new HibernateCallback(){ public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(hql); query.setFirstResult(startRow); query.setMaxResults(pageSize); List list = query.list(); return list; } } } protected void execute(final String hql) { getHibernateTemplate().execute(new HibernateCallback(){ public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(hql); return query.executeUpdate(); } } } 然后子类dao中所有需要分页的都用getPage方法,所有需要对数据库数据执行操作的使用execute方法,只要使用这两个方法就能实现原来的两个callback类实现的方法了 而且不存在线程安全问题,也不存在代码冗余问题,无论如何也只有2个内部类。。。 貌似这个方法是最好的。。。正是我一直以来寻求的方法。。。。还真是灵光一闪阿。。。 想了很久了,没想到突然想到了。。。哈哈哈哈 大家觉得如何? |
|
返回顶楼 | |
发表时间:2009-04-09
用ThreadLocal,不行?
|
|
返回顶楼 | |
发表时间:2009-04-09
欣水寓言 写道 突然想到了一个思路
就是dao的父类中定义两个方法 protected List getPage(final String hql, final int startrow,final int pagesize) { return getHibernateTemplate().executeFind(new HibernateCallback(){ public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(hql); query.setFirstResult(startRow); query.setMaxResults(pageSize); List list = query.list(); return list; } } } protected void execute(final String hql) { public synchronized Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(hql); return query.executeUpdate(); } } } 然后子类dao中所有需要分页的都用getPage方法,所有需要对数据库数据执行操作的使用execute方法,只要使用这两个方法就能实现原来的两个callback类实现的方法了 而且不存在线程安全问题,也不存在代码冗余问题,无论如何也只有2个内部类。。。 貌似这个方法是最好的。。。正是我一直以来寻求的方法。。。。还真是灵光一闪阿。。。 想了很久了,没想到突然想到了。。。哈哈哈哈 大家觉得如何? 我说的用参数代替实例变量就是这个意思 |
|
返回顶楼 | |
发表时间:2009-04-09
xieyongwei 写道 用ThreadLocal,不行? 总不能每次查询的时候都用它吧? 代码冗余严重。。 |
|
返回顶楼 | |