论坛首页 Java企业应用论坛

关于DAO API的取舍

浏览 28071 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-08-27  
DAO
Hibernate对于DAO操作确实提供了很多的帮助,我做了一个Hibernate的封装,所有基本的CRUD的操作都可以在一两个语句内解决。
问题来了,按照构架要求,每一个子应用需要一个Dao相对应,为此,我做了一系列的Dao接口,包含Dao的Hibernate实现,但是在Dao的Hibernate实现类中大多只需要简单调用Hibernate封装类就行了。
这时,我还有没有必要维护一个庞大的Dao API?能否违反构架的要求,在业务逻辑层直接调用Hibernate封装类?毕竟,构架是为了应用服务的,我想。
   发表时间:2004-08-27  
而且,在设计Dao API时每每都要有很多API想象不到,这些API需求往往在开发业务逻辑时暴露出来,这时,即需要修改Dao的接口类,又需要增加Dao的实现类的实现。按照Dao的思想,它需要接口类、实现类、Factory类等,但是如果采样Hibernate的话,是否只要有一个Dao实现类就行了?或者只要有一个Hibernate的封装类就行?毕竟,简洁,是程序的好坏的一个重要评判标准,我认为。
0 请登录后投票
   发表时间:2004-08-27  
我也遇到和楼主同样的问题,感觉DAO过于庞大。

目前我的做法比较偷懒:
public class BaseDAOImpl implements BaseDAO {
		public void insertObject(Object obj);throws HibernateException {

				Transaction tx = null;	
			
				try{
					Session session = HibernateUtil.currentSession();;
					tx= session.beginTransaction();;
					session.save(obj);;
					session.flush();;
					tx.commit();;			
				}catch(Exception e);{
					e.printStackTrace();;
					HibernateUtil.rollback(tx);;	
				}finally {
					HibernateUtil.closeSession();;
				}
		}
	
		public void deleteObject(Object obj);throws HibernateException{
			
				Transaction tx = null;
		
				try{
					Session session = HibernateUtil.currentSession();;
					tx= session.beginTransaction();;
					session.delete(obj);;
					session.flush();;			
					tx.commit();;			
				}catch(Exception e);{
					e.printStackTrace();;
					HibernateUtil.rollback(tx);;	
				}finally {
					HibernateUtil.closeSession();;
				}
		}
	
		public void updateObject(Object obj);throws HibernateException{
	
				Transaction tx = null;
		
				try{
					Session session = HibernateUtil.currentSession();;
					tx= session.beginTransaction();;	
					session.saveOrUpdate(obj);;
					session.flush();;
					tx.commit();;			
				}catch(Exception e);{
					e.printStackTrace();;
					HibernateUtil.rollback(tx);;	
				}finally {
					HibernateUtil.closeSession();;
				}
		}

}


在没有父子关系的情况下,通过写这个基类,完成基本的三种操作,其他的DAO类继承这个基类,并且在此基础上继续写查询函数。在进行插入、修改和删除操作时,只要将特定的类作为参数传入,利用java下塑造型的能力完成操作。

这样的做法比较偷懒,不过对于没有父子关系的简单情况可以节省很多代码。不过我也在想,对于有父子关系的情况,是不是在上述类的基础上,继续写几个函数,完成相应的功能,其他的DAO只要继承这个类就好了?

想法还不很成熟,大家多多指正批评!
0 请登录后投票
   发表时间:2004-08-27  
如果直接利用Hibernate,肯定爽快的多,但是要以丧失移植性为代价,如果项目哪天不用Hibernate了,怎么办?宏观的东西,太大。我觉的你还是先看看论坛中的帖子吧,关于DAO的讨论不少。呵呵,开始,坛主也是这么和我说的。
0 请登录后投票
   发表时间:2004-08-27  
我的做法几乎和你一样,然后针对具体应用,继承这个类,然后去封装。但,由于工时紧,仓促的写了很多方法,现在看来,利用Hibernate特性和放射机制,可以瘦身的。在我的基本的BasicDAO中,只有查询让我头疼,我把它与具体应用相结合。
0 请登录后投票
   发表时间:2004-08-27  
nesta 写道
如果直接利用Hibernate,肯定爽快的多,但是要以丧失移植性为代价,如果项目哪天不用Hibernate了,怎么办?宏观的东西,太大。我觉的你还是先看看论坛中的帖子吧,关于DAO的讨论不少。呵呵,开始,坛主也是这么和我说的。

Dao出现的原因我想有两个,一个是能够在不同数据库系统之间进行方便移植,这也是Dao模式要出现接口类、实现类、工厂类的原因;另一个是在一个统一的地方处理数据库操作,方便维护。
但是使用了Hibernate后,它本身就可以封装多种数据库,所以无需Dao相关类的协作,第二,hibernate通过封装后可以很简洁的处理了数据库操作,维护更为方便。
我想,既然现在项目使用了Hibernate,而且还比较不错,那替换下来的可能性就会很小,所以您说的“丧失移植性为代价”我有些异议。
0 请登录后投票
   发表时间:2004-08-27  
nesta 写道
我的做法几乎和你一样,然后针对具体应用,继承这个类,然后去封装。但,由于工时紧,仓促的写了很多方法,现在看来,利用Hibernate特性和放射机制,可以瘦身的。在我的基本的BasicDAO中,只有查询让我头疼,我把它与具体应用相结合。

   没错,这也就是我发贴的原因,就是感觉有很多的查询,所以根据Dao的模式就要增加很多的Dao API接口,我的意思是把HSQL写在业务逻辑层中,让业务逻辑层调用封装的Hibernate接口,这样Dao的API就非常简单了。
  业务逻辑中的HSQL确实当需要替换Hibernate时带来不少麻烦,但需要替换掉Hibernate的几率应该很小。
0 请登录后投票
   发表时间:2004-08-27  
那是你认为不替换,可是如果要替换呢?再说HSQL,如果你写过SQL进行查询,写HSQL没问题,虽然HSQL是针对对象的,但其结构仿佛和SQL还是差不多(当然,Hibernate就是这么映射的,因为是ORM,好像是废话),但对于没写过SQL的Java程序员,还是有点难度。希望3.0中的Criteria能够更好。
0 请登录后投票
   发表时间:2004-08-27  
出于松耦合的考虑,我认为业务逻辑层中不应当牵涉到任何持久层实际操作,应当做到透明访问持久层,仅仅处理业务对象之间的关系和逻辑,与持久层的依赖越少越好。HQL写在Logic里面我觉得是非常不好的一件事情。你没办法做任何的持久层修改。
我做的DAO都在考虑写一个统一的Filter借口来实现标准查询而不是直接使用Criteria
0 请登录后投票
   发表时间:2004-08-27  
引用

出于松耦合的考虑,我认为业务逻辑层中不应当牵涉到任何持久层实际操作,应当做到透明访问持久层,仅仅处理业务对象之间的关系和逻辑,与持久层的依赖越少越好。HQL写在Logic里面我觉得是非常不好的一件事情。


强烈同意!

不过我感觉如果含有大量的查询操作,DAO依然会非常庞大,最好有一个通用的HQL生成器。根据业务逻辑传过来的参数,动态生成HQL。或许这是可行的,因为毕竟也就是SELECT,FROM,WHERE,ORDER BY这些东西,如果强大一点,最好支持表的连接什么的就好了。

我就曾经做过一个类似的,不过非常简单,而且和业务逻辑相关,没有普遍性。
1 请登录后投票
论坛首页 Java企业应用版

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