2008-04-18
简单说两句关于DAO的看法。
关键字: dao, jpa
我觉得如果对Persistent的理解已经到了JPA的时代,那么DAO是不需要的,甚至是不能要的。
先说为什么不需要。
持久的目的是什么?是存储对象的瞬时状态。将其简单理解为对数据库的CRUD是比较狭隘的。如果,内存足够大、计算机永远不会断电,程序员永远不反错误,那么可以不去持久化。
以JPA(Hibernate)的观点来看,一个对象只有两种状态:持久的和非持久的。让一个非持久的对象变为持久对象只需调用persist ()方法将其加入持久域;让一个持久的对象变为持久对象则调用remove()方法使其脱离持久域;如果让一个持久对象刷新其状态就调用flush()方法;如果想undo那么就refresh()。至于那些烦人琐事,让Hibernate那个倒霉蛋去干吧。事情就是这么简单。
如果看透了这一点,那么DAO就可以去光荣下岗了。
再说为什么不能要。
这个解释起来很简单,看看代码就知道了。
很简单的一对多关联,与之对应有了PersonDao和SomethingDao,它们是的实现类中用Hibernate完成CRUD。
来看看“R”吧,它就是把DAO送进坟墓的人。
如果你不想在Hibernate一棵树上吊死,那么就用JPA吧。如果你也不想在JPA上吊死那就自己定义一个XXXPA也可以。不过,在这之前,先认真地想一想你所知道的软件的生命周期内是不是真的会换掉Hibernate呢?
先说为什么不需要。
持久的目的是什么?是存储对象的瞬时状态。将其简单理解为对数据库的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
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?
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摆到哪里?
如果你不用DAO,那把hql语句或者sql摆到哪里?
我会使用NamedQuery,即使有DAO,我也不愿意看到Java Code里混入QL。
姜太公
2008-04-19
使用DAO,意义在于可以让业务逻辑层专注业务逻辑,不用关心持久化操作,其次是实现持久层的可插接性。
JPA只不过是把几种持久化框架封装了一下,根本不能替代DAO。难道你想在业务逻辑里填满EQL?
JPA只不过是把几种持久化框架封装了一下,根本不能替代DAO。难道你想在业务逻辑里填满EQL?
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 859 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
问题:列举Spring框架中使 ...
呵呵。。无中生有。有中还无啊。 模式只不过是别人经验的总结。也许经验丰富了。 ...
-- by penghao122 -
问题:列举Spring框架中使 ...
Factory Method Template MethodStrategy s ...
-- by fantasybei -
问题:列举Spring框架中使 ...
facadeabstract factorydelegateadapterabs ...
-- by willim -
问题:请写一段代码说明如 ...
TomHornson 写道http://www.ibm.com/develope ...
-- by suke -
问题:请写一段代码说明如 ...
yujianqiu 写道 问题:请写一段代码说明如何实现Singleton模式 ...
-- by wolfbrood






评论排行榜