论坛首页 Java企业应用论坛

Spring的DAO设计实践

浏览 108809 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-11-02  
HibernateTemplate 中不能用Query?使用分页麻烦?不是很理解。
那我下面的代码是否有问题?
public List searchByOwnerId(long ownerId, int start, int range); {
    List l = new ArrayList();;
    Session s = this.getSession();;
    try {
      Query q = s.createQuery(FIND_BY_OWNERID);;
      q.setLong(0, ownerId);;
      q.setFirstResult(start);;
      q.setMaxResults(range);;
      l = q.list();;
    }
    catch (HibernateException ex); {
      log.error("search UserResponsion by ownerId error", ex);;
    }
    finally {
      this.closeSessionIfNecessary(s);;
      return l;
    }
  }
0 请登录后投票
   发表时间:2004-11-06  
HibernateTemplate 可以直接获取 Session,为什么要使用HibernateCallBackup()(特别是对于分页查询)?真的不是很理解,有人能帮助解答么?上面的代码是否有问题?谢谢
0 请登录后投票
   发表时间:2004-11-11  
HibernateTemplate 可以直接获取 Session,为什么要使用HibernateCallBackup()(特别是对于分页查询)?真的不是很理解,有人能帮助解答么?上面的代码是否有问题?谢谢[/quot]
请问你的作为参数传入的session是哪里来的?
请看spring关于hibernate部分的源码,你就很快能熟悉spring精巧的设计。
0 请登录后投票
   发表时间:2004-11-13  
public class UserResponsionDAOHibernate
    extends HibernateDaoSupport
    implements UserResponsionDAO {
  private static Log log = LogFactory.getLog(UserResponsionDAOHibernate.class);;

  private static String FIND_BY_OWNERID =
      "from UserResponsion a where a.ownerId = ?";
 
  public List searchByOwnerId(long ownerId, int start, int range); {
    List l = new ArrayList();;
    Session s = this.getSession();;
    try {
      Query q = s.createQuery(FIND_BY_OWNERID);;
      q.setLong(0, ownerId);;
      q.setFirstResult(start);;
      q.setMaxResults(range);;
      l = q.list();;
    }
    catch (HibernateException ex); {
      log.error("search UserResponsion by ownerId error", ex);;
    }
    finally {
      this.closeSessionIfNecessary(s);;
      return l;
    }
  }

}


那我再将代码贴得完整些,session 是继承 HibernateDaoSupport,本身就具备的成员变量。

对 spring 我仍停留在使用阶段,没有打算去看它的源码。

只是我看过前面的帖子说HibernateTemplate 不方便,甚至要 HibernateCallBackup(),不太明白为什么有这样的结论。
0 请登录后投票
   发表时间:2004-11-20  
	public Object execute(HibernateCallback action) throws DataAccessException {
		Session session = (!isAllowCreate() ?
				SessionFactoryUtils.getSession(getSessionFactory(), false) :
				SessionFactoryUtils.getSession(
						getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator()));
		boolean existingTransaction = TransactionSynchronizationManager.hasResource(getSessionFactory());
		if (!existingTransaction && getFlushMode() == FLUSH_NEVER) {
			session.setFlushMode(FlushMode.NEVER);
		}
		try {
			Object result = action.doInHibernate(session);
			flushIfNecessary(session, existingTransaction);
			return result;
		}
		catch (HibernateException ex) {
			throw convertHibernateAccessException(ex);
		}
		catch (SQLException ex) {
			throw convertJdbcAccessException(ex);
		}
		catch (RuntimeException ex) {
			// callback code threw application exception
			throw ex;
		}
		finally {
			SessionFactoryUtils.closeSessionIfNecessary(session, getSessionFactory());
		}
	}


以上部分是HibernateTemplate的execute方法的源代码,请注意这几行:

		Session session = (!isAllowCreate() ?
				SessionFactoryUtils.getSession(getSessionFactory(), false) :
				SessionFactoryUtils.getSession(
						getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator()));
		boolean existingTransaction = TransactionSynchronizationManager.hasResource(getSessionFactory());
		if (!existingTransaction && getFlushMode() == FLUSH_NEVER) {
			session.setFlushMode(FlushMode.NEVER);
		}


这几行代码是和事务相关的,如果你不用Template,那么如果你自己用Session来操作的话,这几行代码不应该忽略掉吧?
0 请登录后投票
   发表时间:2004-11-20  
研读HibernateTemplate的源代码,主要是execute方法,其中有这些地方都是和事务相关的:

boolean existingTransaction = TransactionSynchronizationManager.hasResource(getSessionFactory(););;


当前执行上下文是否存在事务

if (!existingTransaction && getFlushMode(); == FLUSH_NEVER); {
    session.setFlushMode(FlushMode.NEVER);;
}


不存在事务的时候,设置Hibernate的FlushMode

引用
flushIfNecessary(session, existingTransaction);


当有事务存在的时候,尽可能flush。

这些事务代码虽然也不必非写不可,但是如果你不用HibernateTemplate,那么似乎还是写上比较好,那么看起来如果不用Template的CallBack,自己写的代码势必更加臃肿些。

不过即使用Template,写inner Class也挺难看,实际上都差不多,呵呵。
0 请登录后投票
   发表时间:2004-11-21  
同意Robbin关于Template的看法
但是Robbin推荐的那篇文章写的方式过于简单
如果使用代码生成器的话,应该给用户足够的定制空间
DAO至少应是四层继承结构
RootDAO--提供HibernateDAOSupport
BaseRootDAO--继承RootDAO,无方法,定制全局DAO方法用
BaseXXDAO--继承BaseRootDAO,对特定PO类提供的模板支持
XXDAO--继承BaseXXDAO,无方法,定制特定DAO方法
0 请登录后投票
   发表时间:2004-11-23  
拦截器的缺点太明显
不说checked Exception的好坏
光是配置文件中的设置就够烦人的了
0 请登录后投票
   发表时间:2004-12-21  
我现在做的简单实现是这样的:

dao那边分为几类,有一个BaseDAO,执行三个方法save,update,saveorupdate。

还有一个find类,有直接利用HibernateTemplate方法的简单find,也有自定义的find。

另外还可能有一个remove类,可能要支持一些复杂的remove。

service这边暂时就一个service,通过Aop的方式,注入了BaseDAO和FindDAO。

我希望dao层保持通用性,而一些变化和组合在service上面来做,所以就把dao分的比较细。

代码简单如下:

BaseDAO:
public interface IBaseDAO {

  public void saveObject(Object o);;

  public void updateObject(Object o);;

  public void storeObject(Object o);;

}


FindDAO:
public interface IFindDAO {

  public Object findbyid(Class clazz, String id);;

  public List findforpage(String querystring, Class clazz, int firstnode, int noderange);;

  public int findallcount(Class clazz);;

}


service:
public interface IService extends IBaseDAO, IFindDAO {

  public void setdao1(IBaseDAO basedao);;

  public void setdao2(IFindDAO finddao);;

}


这样的实现有什么缺点么? 请不吝赐教。
0 请登录后投票
   发表时间:2004-12-22  
我是用一个类将HibernateDaoSupport封装做为整个DAO层,SERVICE层做一个抽象类,用IOC注入DAO层的那个类,所有SERVICE层的实现类从该抽象类继承。调用DAO层的类实现数据库存储。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics