论坛首页 Java企业应用论坛

关于DAO层的疑惑!!!平地一声雷

浏览 24791 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (14) :: 隐藏帖 (6)
作者 正文
   发表时间:2011-08-02  

最近一直在考虑一个问题,在S2SH开发中,DAO层到底应该怎么写?是一个通用DAO呢还是各个Model的DAO分开呢?

 

如果是各个MOdel的DAO分开写,这样会有很多重复代码,几乎每个DAO类里面都包含save,delete,update,load等一样标签的方法,和重用性相抵触,而且在application.xml中配置非常麻烦,每个DAO都得引用sessionFactory,这样配置文件也有很多冗余!

 

我个人认为,dao层只应提供数据持久化接口,和数据库,Service层均没有关系,如果持久化框架变了,比如不用Hibernate,而改用ibatIS,那么只需要将DAO里面的实现稍作改动,整个系统就可以流畅运行.所以,这就要求在Service层不要写HQL或者QBC,Service层专注调用DAO层接口为Action层提供服务,和DAO层无耦合.这样如果写一个通用DAO层的话,就会提高代码重用性,并且xml配置也很简洁,只要配置一个通用的dao就可以了,但是却使以牺牲灵活性为前提的,比如在Service层需要一个按属性查询的方法,那么在DAO层就要写where子句(where xxx=yyy),但是通用dao不可能知道xxx,怎么办呢?

 

如果通用DAO层接受Service层传来的HQL的话,那就会很容易写出一个灵活性高,重用性强的DAO通用层,但是这样又有了耦合性,持久化框架变化的话要改变的代码会很多,甚至可以说是牵一发而动全身.

 

所以,到底该怎么设计DAO层呢,思考良久,觉得,还是通用DAO比较合理一点,配置文件少,重用性高,这是大方向,然后如何写出一个和Service层无关的又有很高灵活性的DAO层,一直困扰我,各位大虾们,请说说你们的看法,你们有没有更好的方法?或者我的这个困惑是不是应该有的?该不该放弃低耦合?

 

 

最后,我希望大家不要用经验和我谈问题,经验都是看别人的代码学来的,真正思考过这个问题的才有发言权...

   发表时间:2011-08-02  
CRUD中最麻烦的是查询。每个对象都有一大堆查询方法,千奇百怪五花八门。所以现在的Dao膨胀得很厉害。加上很多人不能理清楚Service和Dao的关系,Action里都是HQL。
所以如何在隔绝具体实现的情况下零花灵活查询才是问题所在。希望JPA2能够给出一些更好的解决办法。虽然Hibernate和Jpa中也可以使用命名查询。但是很多时候查询参数是不定的。比如查一个对象的创建时间在某个起始时间到某个结束时间之间。这是一个很常见的情况。但是这其实是三个查询,一个是只有开始时间、一个只有结束时间还有就是两个都有。命名查询就需要3个。推论到所有的对象上,命名查询会疯长的。
0 请登录后投票
   发表时间:2011-08-02  
feiyang404 写道
CRUD中最麻烦的是查询。每个对象都有一大堆查询方法,千奇百怪五花八门。所以现在的Dao膨胀得很厉害。加上很多人不能理清楚Service和Dao的关系,Action里都是HQL。
所以如何在隔绝具体实现的情况下零花灵活查询才是问题所在。希望JPA2能够给出一些更好的解决办法。虽然Hibernate和Jpa中也可以使用命名查询。但是很多时候查询参数是不定的。比如查一个对象的创建时间在某个起始时间到某个结束时间之间。这是一个很常见的情况。但是这其实是三个查询,一个是只有开始时间、一个只有结束时间还有就是两个都有。命名查询就需要3个。推论到所有的对象上,命名查询会疯长的。


这段话是我从其他地方粘来的,我觉得一句话特别重要:"很多人不清楚Service和Dao的关系,Action里都是HQL",这句话虽有点夸张,但是Service层里有HQL确实常见的不能再常见,能不能设计出一种通用和Service没有任何关系的DAO层呢?QBC好像也实现不了,各位,有没有解决办法?
0 请登录后投票
   发表时间:2011-08-03  

通用Dao里只是装着各个通用的方法,每个Model还应该有个属于自己的Dao,用来存储自己特有的方法.
0 请登录后投票
   发表时间:2011-08-03  
小鑫。 写道

通用Dao里只是装着各个通用的方法,每个Model还应该有个属于自己的Dao,用来存储自己特有的方法.


是有个BaseDAO,有个BaseDAOImpl,然后xxxDAO,xxxDAOImpl? 这样的话,接口继承关系应该怎么写?实现关系应该怎么写?
我以前也有过这样的想法,但是这样xml配置文件还是要针对每个xxxDAO做配置,很是麻烦,如果这样,我到宁愿牺牲耦合性,在Service层构造HQL,然后传到DAO层来.写一个HQL应该比写一个DAO类简单吧?
0 请登录后投票
   发表时间:2011-08-03  
feiyang404 写道
CRUD中最麻烦的是查询。每个对象都有一大堆查询方法,千奇百怪五花八门。所以现在的Dao膨胀得很厉害。加上很多人不能理清楚Service和Dao的关系,Action里都是HQL。
所以如何在隔绝具体实现的情况下零花灵活查询才是问题所在。希望JPA2能够给出一些更好的解决办法。虽然Hibernate和Jpa中也可以使用命名查询。但是很多时候查询参数是不定的。比如查一个对象的创建时间在某个起始时间到某个结束时间之间。这是一个很常见的情况。但是这其实是三个查询,一个是只有开始时间、一个只有结束时间还有就是两个都有。命名查询就需要3个。推论到所有的对象上,命名查询会疯长的。



Action里面都是HQL 需要注意事物问题。

一般都是封装一个公共Dao , 里面除了CUDI 你可以扩展下动态查询 ,及获取数据连接的方法。
0 请登录后投票
   发表时间:2011-08-03  
feiyang404 写道
在Service层需要一个按属性查询的方法,那么在DAO层就要写where子句(where xxx=yyy),但是通用dao不可能知道xxx,怎么办呢?

 

如果通用DAO层接受Service层传来的HQL的话,那就会很容易写出一个灵活性高,重用性强的DAO通用层,但是这样又有了耦合性,持久化框架变化的话要改变的代码会很多,甚至可以说是牵一发而动全身.

 

通用DAO可以做到把根据where条件不同查询,每个DAO只需要去继承它就可以了,然后自己实现些特殊的对操作

service可以控制事务什么的,还可以在service通过spring注入多个DAO操作

0 请登录后投票
   发表时间:2011-08-03  
LZ真不虚心,不告诉你了
0 请登录后投票
   发表时间:2011-08-03  
一般,建议,仍然为每个实体类提供一个DAO接口,在此前提下,再来个BaseDAO,来实现CUD操作,以及根据ID查询的操作,五花八门的查询方法,才是各个实现类的重点所在。当然,设计DAO时,还有个不得不考虑的问题,分页。另一个需要思考的问题是,当系统足够膨大时,我们必须思考的是,如何对Service层的纵向分割。那我们在设计DAO层时,是不是应该考虑,将一些POJO的DAO合并到一起DAO中呢?我想,关键的是,这个切分的标准。目前我唯一想到的是,DDD思想中的聚类。
0 请登录后投票
   发表时间:2011-08-03  
一个抽象类,用上泛型,能好点吧。
0 请登录后投票
论坛首页 Java企业应用版

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