职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 1765|回复: 10

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

[复制链接]
醉倚西风 发表于 2011-9-4 09:38 | 显示全部楼层 |阅读模式
最近一直在考虑一个问题,在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-9-4 09:38 | 显示全部楼层
CRUD中最麻烦的是查询。每个对象都有一大堆查询方法,千奇百怪五花八门。所以现在的Dao膨胀得很厉害。加上很多人不能理清楚Service和Dao的关系,Action里都是HQL。
所以如何在隔绝具体实现的情况下零花灵活查询才是问题所在。希望JPA2能够给出一些更好的解决办法。虽然Hibernate和Jpa中也可以使用命名查询。但是很多时候查询参数是不定的。比如查一个对象的创建时间在某个起始时间到某个结束时间之间。这是一个很常见的情况。但是这其实是三个查询,一个是只有开始时间、一个只有结束时间还有就是两个都有。命名查询就需要3个。推论到所有的对象上,命名查询会疯长的。

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


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

fossil 发表于 2011-9-4 09:39 | 显示全部楼层

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

愚人 发表于 2011-9-4 09:39 | 显示全部楼层
小鑫。 写道

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


是有个BaseDAO,有个BaseDAOImpl,然后xxxDAO,xxxDAOImpl? 这样的话,接口继承关系应该怎么写?实现关系应该怎么写?
我以前也有过这样的想法,但是这样xml配置文件还是要针对每个xxxDAO做配置,很是麻烦,如果这样,我到宁愿牺牲耦合性,在Service层构造HQL,然后传到DAO层来.写一个HQL应该比写一个DAO类简单吧?

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



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

一般都是封装一个公共Dao , 里面除了CUDI 你可以扩展下动态查询 ,及获取数据连接的方法。

fossil 发表于 2011-9-4 09:39 | 显示全部楼层
feiyang404 写道
在Service层需要一个按属性查询的方法,那么在DAO层就要写where子句(where xxx=yyy),但是通用dao不可能知道xxx,怎么办呢?

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

通用DAO可以做到把根据where条件不同查询,每个DAO只需要去继承它就可以了,然后自己实现些特殊的对操作
service可以控制事务什么的,还可以在service通过spring注入多个DAO操作

芷馨 发表于 2011-9-4 09:39 | 显示全部楼层
LZ真不虚心,不告诉你了

走失的猫咪 发表于 2011-9-4 09:39 | 显示全部楼层
一般,建议,仍然为每个实体类提供一个DAO接口,在此前提下,再来个BaseDAO,来实现CUD操作,以及根据ID查询的操作,五花八门的查询方法,才是各个实现类的重点所在。当然,设计DAO时,还有个不得不考虑的问题,分页。另一个需要思考的问题是,当系统足够膨大时,我们必须思考的是,如何对Service层的纵向分割。那我们在设计DAO层时,是不是应该考虑,将一些POJO的DAO合并到一起DAO中呢?我想,关键的是,这个切分的标准。目前我唯一想到的是,DDD思想中的聚类。

月上萧萧 发表于 2011-9-4 09:40 | 显示全部楼层
一个抽象类,用上泛型,能好点吧。
qnajpfzu 发表于 2012-5-21 23:21 | 显示全部楼层

支持!

您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-3 10:32 , Processed in 0.122195 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表