2008-04-18

简单说两句关于DAO的看法。

关键字: dao, jpa
我觉得如果对Persistent的理解已经到了JPA的时代,那么DAO是不需要的,甚至是不能要的。
先说为什么不需要。
持久的目的是什么?是存储对象的瞬时状态。将其简单理解为对数据库的CRUD是比较狭隘的。如果,内存足够大、计算机永远不会断电,程序员永远不反错误,那么可以不去持久化。
以JPA(Hibernate)的观点来看,一个对象只有两种状态:持久的和非持久的。让一个非持久的对象变为持久对象只需调用persist ()方法将其加入持久域;让一个持久的对象变为持久对象则调用remove()方法使其脱离持久域;如果让一个持久对象刷新其状态就调用flush()方法;如果想undo那么就refresh()。至于那些烦人琐事,让Hibernate那个倒霉蛋去干吧。事情就是这么简单。
如果看透了这一点,那么DAO就可以去光荣下岗了。
再说为什么不能要。
这个解释起来很简单,看看代码就知道了。
public class Person {
    private int id;
    private List<Something> things;
    ...
}
public class Something{
    private int id;
    private Person owner;
    private String name;
    ...
}

很简单的一对多关联,与之对应有了PersonDao和SomethingDao,它们是的实现类中用Hibernate完成CRUD。
来看看“R”吧,它就是把DAO送进坟墓的人。
public void doSomething() {
    Person me = personDao.get(myId);
    //我可以这样做吗?
    List<Something> myThings  = person.getThings();
    //还是要这样做?
    myThings = somethingDao.getThingsOf(me);
}

如果你不想在Hibernate一棵树上吊死,那么就用JPA吧。如果你也不想在JPA上吊死那就自己定义一个XXXPA也可以。不过,在这之前,先认真地想一想你所知道的软件的生命周期内是不是真的会换掉Hibernate呢?
评论
pig345 2008-04-25
没办法,只能再次贴出老帖子:

《RichDomainObject的架构设计中,是否可以抛弃DAO?》

http://pig345.javaeye.com/blog/79822
peak 2008-04-24
楼主说了半天不就是把一些对象的存取通过hibernate自己的映射关系以及级联来完成,这种情况只适合没有业务需求的情况的时候,如果你getsomething的List的时候要过滤掉一些数据的话你又怎么做呢?别说直接操作List……
池中物 2008-04-23
引用
持久的目的是什么?是存储对象的瞬时状态。将其简单理解为对数据库的CRUD是比较狭隘的。如果,内存足够大、计算机永远不会断电,程序员永远不反错误,那么可以不去持久化。


这个我也想过, 我觉得用仓储来形容更好, 无论持不持久, 都需要在用的时候取到对象, 那么就是到仓储去取, 用完了对象自动保存在仓储里
changshuangyi 2008-04-23
关于这个问题,还有待于讨论呢
Joo 2008-04-22
teclogid 写道
Joo 写道
danlley 写道
不知道JPA\Hibernate\JDO他们之间到底是什么关系


JDO自成一派
JPA实际上就是sun封装过了的Hibernate

拜托!!你上面的概念哪来的?JPA是规范,哪是什么sun封装了的。有基于hibernate的一个jpa实现。当然还有一个apache的实现:openjpa
btw:楼主应该是刚工作几个月,而且不适合干编程,思维逻辑有问题。


sorry 的确信口雌黄了
JPA乃标准是也 Hibernate或者TopLink都是能符合规范的具体实现
fhjxp 2008-04-22
lgcpeter 写道
yujianqiu 写道
icewubin 写道

楼主的话,换一种理解就是单DAO设计。


这样的表述比较妥当。

赞成,应该是单DAO,通用的一个DAO。

不是很复杂的系统,单dao设计应该挺合适的
lgcpeter 2008-04-22
yujianqiu 写道
icewubin 写道

楼主的话,换一种理解就是单DAO设计。


这样的表述比较妥当。

赞成,应该是单DAO,通用的一个DAO。
yujianqiu 2008-04-21
icewubin 写道

楼主的话,换一种理解就是单DAO设计。


这样的表述比较妥当。
slaser 2008-04-21
另外,我同意楼主不要dao的做法。至少在小项目里面,往service层里面注入entitymanager就可以了,这个问题以前很多地方讨论过。
slaser 2008-04-21
teclogid 写道
Joo 写道
danlley 写道
不知道JPA\Hibernate\JDO他们之间到底是什么关系


JDO自成一派
JPA实际上就是sun封装过了的Hibernate

拜托!!你上面的概念哪来的?JPA是规范,哪是什么sun封装了的。有基于hibernate的一个jpa实现。当然还有一个apache的实现:openjpa
btw:楼主应该是刚工作几个月,而且不适合干编程,思维逻辑有问题。

看不出JPA规范的重要性。Hibernate已经基本是事实标准了,sun和oracle等厂商为了自己的orm不被淘汰强行搞出JPA标准,但是实际上大部分项目还是用的hibernate,而且由于JPA标准的不完善导致annotation异常丑陋,说sun封装了hibernate是抬举JPA了,实际是sun阉割了hibernate。

 

teclogid 2008-04-21
Joo 写道
danlley 写道
不知道JPA\Hibernate\JDO他们之间到底是什么关系


JDO自成一派
JPA实际上就是sun封装过了的Hibernate

拜托!!你上面的概念哪来的?JPA是规范,哪是什么sun封装了的。有基于hibernate的一个jpa实现。当然还有一个apache的实现:openjpa
btw:楼主应该是刚工作几个月,而且不适合干编程,思维逻辑有问题。
Joo 2008-04-21
danlley 写道
不知道JPA\Hibernate\JDO他们之间到底是什么关系


JDO自成一派
JPA实际上就是sun封装过了的Hibernate
danlley 2008-04-21
不知道JPA\Hibernate\JDO他们之间到底是什么关系
seemoon 2008-04-21
我看楼主提的问题糊涂,然后一群人也在糊涂的讨论一个糊涂的问题,最后是看的人也糊涂
yelongyelong 2008-04-21
引用
当通过PersonDAO取得一个Person对象后完全没有必要再通过SomethingDao取得Something了

引用
通过PersonDAO取得一个Person对象

你这不是在用Dao吗?
引用
完全没有必要再通过SomethingDao取得Something

为了拿一个Something,你先拿出Person再拿出他的Something,再在Something中拿一个?
照这么说,要获取一个用户的信息,得先找到他的老祖宗,再在第几代传人中找到他?
icewubin 2008-04-20
姜太公 写道
使用DAO,意义在于可以让业务逻辑层专注业务逻辑,不用关心持久化操作,其次是实现持久层的可插接性。
JPA只不过是把几种持久化框架封装了一下,根本不能替代DAO。难道你想在业务逻辑里填满EQL?


有机会我会系统地说一下,我想说,谁说HQL、SQL、EQL就一定不是业务逻辑了,当然可以放在一起。楼主的话,换一种理解就是单DAO设计。

我的理解就是,持久化的复杂事(基础CRUD)应该屏蔽的,但是你们老把业务级的CRUD和基础CRUD混为一谈。

这里的误区,很多人首先误以为业务CRUD就是基础CRUD,应该要屏蔽,而且要加以复用,“加以复用”是对的,但是概念上混为一谈。

举例:在一个DAO或者Manager中实现save()方法,

public void save(Order order) {
    some code here//判断数据库中是否已经逻辑上重复的记录,或者说是自然键重复的记录
    super.save(order);//super也可以是EntityDao,或EntityManager
}

“super.save(order);”才是已经被封装的基础CRUD,但是整个方法就是个业务级的CRUD,概念上先分清楚。

不是为了封装而封装,基于业务逻辑的 HQL、QBC、SQL、EQL就应该和JavaCode混在一起的,没什么不好的,看你自己如何组织代码了。比如你QBC用的非常好的话,代码组织就非常清晰,不会出现根据条件拚HQL那样稍嫌复杂的代码,但是复杂的查询从可读性上来讲又可以考虑HQL。技巧上不展开了,有机会我再详细说。

所以为了分清概念,最好就不要再取DAO的名字,就叫Manager,可以再用Service一层,减少循环依赖出现的麻烦,当然也可以两层合并。
lingzantia 2008-04-20
楼主的意思是当one-to-many关联时只需要在one端负责取得many端的对象而不需要many端的dao?那至少有一个条件:你能保证many端不需要单独存取!
yujianqiu 2008-04-19
Joo 写道
引用
至于那些烦人琐事,让Hibernate那个倒霉蛋去干吧


不知道你说的琐事是什么
在标准的EJB开发中只有JPA没有Hibernate...那这样琐事谁来干


Hibernate是一个JPA实现,也可以用其他厂商的实现,不过我只用过Hibernate。

我正打算写一个简单的xml实现,有兴趣大家可以一起探讨。
不过我猜可能已经有这样的实现了,哪位知道有关的信息,请告诉我一下哦,谢谢。
yujianqiu 2008-04-19
luckaway 写道
DAO只是封装底层的sql语句!提供连接数据库的接口。
如果你不用DAO,那把hql语句或者sql摆到哪里?


我会使用NamedQuery,即使有DAO,我也不愿意看到Java Code里混入QL。
姜太公 2008-04-19
使用DAO,意义在于可以让业务逻辑层专注业务逻辑,不用关心持久化操作,其次是实现持久层的可插接性。
JPA只不过是把几种持久化框架封装了一下,根本不能替代DAO。难道你想在业务逻辑里填满EQL?
发表评论

提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则

您还没有登录,请登录后发表评论

yujianqiu
搜索本博客
最近加入圈子
最新评论