论坛首页 Java企业应用论坛

有了hibernate是否还需要Dao?

浏览 28681 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-12-21  
最近学习使用Struts2+Hibernate,也是分层,web层里放Struts2的action
service层里放业务逻辑对象,持久层里放的是dao+po,对po操作基本放到了dao里,可以我不解的是使用Hibernate的方法我返回本身就是po,为什么大家写程序的时候还写dao呢?我的dao里对po的操作几乎把它细分到了一个方法仅仅一次crud,我通过调用不同的dao里多次方法来实现业务中需要对不同的po进行多次的crud操作的情况,每调用一次dao的一个方法开个session然后对po进行一次crud操作又关session,那么session的缓存不是基本没什么作用了吗?还有一个问题就是通常po对应了一dao又对应了一service,我的dao的方法分的比较细(一个方法仅仅对po进行一次crud),我感觉我的service里仅仅只是重复调用了一遍dao的方法,然后在action中调用service层里不同的service对象实现稍微复杂的业务,我想过是不是service是用来把不同的dao的方法结合起来实现业务中需要对不同的po进行多次的crud操作的情况?这样在action中只要调用service中的方法那action里的代码就清爽了。但是我的action我也分的比较的细,一个action只针对用户的一步操作(多步操作可以用action chain串起来),一个页面可以有不同的action为用户不同的请求服务,action也是根据用户的一步操作命的名,我觉得根本不要把对action的多次操作的这样的业务放到service中,我想去掉service层直接在action中调用dao,原因是我的action是根据用户的一步业务操作命名,作为业务逻辑也好理解,几步操作可以用action chain,原因二是少了service层不用把数据又传到service层再调用一遍,原因三按照 黑体部分(见上面) 的考虑service到是有事情干了,可action干什么呢,难道是为了调service而存在的吗??关于web+service+dao+po这样的分层大家能能简单的说明下那三层究竟各负责什么,另外我知道要根据项目的具体情况合理分层,但我始终不明白service层的具体作用。
归纳下我的疑问:
1使用Hibernate的方法我返回本身就是po,为什么大家写程序的时候还写dao呢?我的dao里对po的操作几乎把它细分到了一个方法仅仅一次crud,每个方法一开session一关session,session的缓存不是几乎形同虚设了吗?
2我的web层的action我也分的比较的细,一个action只针对用户的一步操作(多步操作可以用action chain串起来),是否还需要service层?为什么?
3web(细,struts2支持按namespace对action划分)+service(使用Hibernate实现业务逻辑,稍复杂业务逻辑可以对不同po crud多次可以利用到session缓存)+po 一般情况的项目是不是这样分层更好一些呢?
   发表时间:2007-12-22  
我觉得设计DAO的重要原因是为了将持久化的实现与持久化接口分开。万一哪天你不用Hibernate了,DAO的接口还可以重用。而如果你直接使用Hibernate的话,你的业务逻辑层代码就和Hibernate耦合了。
这只是我肤浅的理解而已,呵呵~
0 请登录后投票
   发表时间:2007-12-22  
管理方便 ,找文件不用debug
0 请登录后投票
   发表时间:2007-12-22  
偶也正在学习之中,如果你在看看spring我想你会恍然大悟的。
但是当你学习这方面的东西时,头脑里必须有一个概念---面象接口编程。
具体它为什么这样分,当然会有它的道理,如果你还是不明白的话,那只能说你对它的思想还不够深入,我建议多读代码,和别人讨论一下。
0 请登录后投票
   发表时间:2007-12-22  
天,我和楼主遇到的问题一模一样,我对分层的认识好像也和楼主差不多:
一个action只针对用户的一步操作
感觉我的service里仅仅只是重复调用了一遍dao的方法

我举个例子来说吧:
我在写一个blog系统,有用户模块、有日志模块、有相册模块、有留言板模块。日志模块有三张表:日志分类表,日志表,日志评论表。

现在我有一个ListWeblogAction,是用来列出指定的用户的所有日志的Action,首先遇到的问题就是这个Action调用的方法应该写在UserService里呢?还是写在WeblogService里?如果写在UserService里,调用的时候直接在方法里写一句user.getWeblogs()返回一个Set,那这个系统的持久层不是非用ORM(或者说非用hibernate)不可了?如果写在WeblogService里,那就得通过userid来查询指定用户的所有日志,这样好像又失去了使用ORM的意义。

第二个问题是这时候Action传给Service层的参数应该是一个UserID还是整个User对象?(这问题好像可以随着第一个问题的解决而解决)

第三个问题就是楼主问的DAO需要不需要的问题了,如果我用UserPO作参数,调用的listWeblog方法在UserService里,那UserService调用的DAO又该做些什么动作呢?好像没有使用DAO的必要了吧?想像一下,我进入某个用户的blog,然后点击导航栏上的“日志”链接,接下来就要显示这个用户的所有日志了,先把这个Detached的UserPO传给UserService,然后在UserService里lock这个UserPO,再调用UserPO的getWeblogs()方法返回指定用户的所有日志集合不就完了,DAO还要做什么?或者把这些操作放在DAO里,那Service又做什么?不是没事可干?就像楼主说的仅仅是把UserPO从Action传到了DAO而已。

还有,从上面的分析里,我感觉一个使用了ORM的系统好像就不能脱离ORM而改用JDBC了,因为一个系统如果使用了ORM,它的业务层的设计和不使用ORM的系统的业务层设计是不一样的。

不知道我说的对不对,我是个初学者,还请各位前辈多多指点!
0 请登录后投票
   发表时间:2007-12-22  
moonranger 写道
我觉得设计DAO的重要原因是为了将持久化的实现与持久化接口分开。万一哪天你不用Hibernate了,DAO的接口还可以重用。而如果你直接使用Hibernate的话,你的业务逻辑层代码就和Hibernate耦合了。
这只是我肤浅的理解而已,呵呵~
感谢你的回答,那用Jpa后是不是不写Dao就可以解决Hibernate耦合的问题了呢?(我认为可以)。另外主要我认为写了Dao后Hibernate的Session缓存的作用大大被削弱了,因为我Dao的每一个方法只进行一次crud操作开个一次Session又马上close掉了。
1 请登录后投票
   发表时间:2007-12-22  
抛出异常的爱 写道
管理方便 ,找文件不用debug
仅此而已吗?能稍微详细点吗?另外看过你在javaeye上的回帖,一般回的第一帖精简的很,如果不是我继续看你以后的回帖,恐怕偶目前还理解不了其中的深意 另外我这样dao每个方法打开session进行一次crud操作后关闭,那Session的缓存基本上利用不上了是不???
1 请登录后投票
   发表时间:2007-12-22  
qmy 写道

现在我有一个ListWeblogAction,是用来列出指定的用户的所有日志的Action,首先遇到的问题就是这个Action调用的方法应该写在UserService里呢?还是写在WeblogService里?如果写在UserService里,调用的时候直接在方法里写一句user.getWeblogs()返回一个Set,那这个系统的持久层不是非用ORM(或者说非用hibernate)不可了?如果写在WeblogService里,那就得通过userid来查询指定用户的所有日志,这样好像又失去了使用ORM的意义。

第二个问题是这时候Action传给Service层的参数应该是一个UserID还是整个User对象?(这问题好像可以随着第一个问题的解决而解决)

还有,从上面的分析里,我感觉一个使用了ORM的系统好像就不能脱离ORM而改用JDBC了,因为一个系统如果使用了ORM,它的业务层的设计和不使用ORM的系统的业务层设计是不一样的。

关于这个问题说说我的想法吧,我认为写到UserService中比较好,因为我写程序首先会画用例图,这里应该有个User的用例它有很多操作比如ListWeblogAction,然后我会根据具体的操作也就是业务逻辑,在找出其中涉及到的实体比如Weblog。还有一点是“通过userid来查询指定用户的所有日志”我认为你的这个操作可以分为两步,首先通过userid找到user然后通过user找Weblog,操作分的越细越有利于以后的重用,比如如果你有一个需求是找userid对应的user的业务呢,那么你又得去写个方法了。但是像我这样写系统的时候操作分的细了,感觉service被我架空的感觉,有点矛盾。我现在在想通过userid找user和通过user找Weblog应该是UserDao的事情,然后两个方法写到一个UserService方法中去,这样UserService是不是感觉干了点活呢???但是如果我又有一个业务是通过userid找user呢???把两个方法合成一个业务逻辑到底放到Action里去,UserService在Action中调用这两个方法还是两个方法写到UserService中的一个方法中去在Action里,UserSercie仅仅调用这一个方法就可以了,有点矛盾,那样好点呢???个人倾向于第一种,但是UserService的方法就变成了重复掉UserDao的方法了
0 请登录后投票
   发表时间:2007-12-22  
xuejianshan 写道
偶也正在学习之中,如果你在看看spring我想你会恍然大悟的。
但是当你学习这方面的东西时,头脑里必须有一个概念---面象接口编程。
具体它为什么这样分,当然会有它的道理,如果你还是不明白的话,那只能说你对它的思想还不够深入,我建议多读代码,和别人讨论一下。
我其实还是懂一点spring的,能够理解面向接口编程。如果说Dao接口可以不让降低我们对数据库访问接口的依赖,Service接口主要可以降低我们对于什么的依赖呢?如果大家略举一例,不胜感激!!!另外我目前写的程序与Hibernate耦合并没有关系,在这样的情况下,大家认为省去Dao是不是一个更好的选择,我一开始就不介意与Hibernate偶和,故均没有写Service接口和Dao接口,但写了Service 和 Dao的一个具体的实现(出于自己一想简化开发省了接口,又惯性使然写了这两个层),请问在这样的情况,大家能否给个建议,Service和Dao的取舍问题,谢谢!
0 请登录后投票
   发表时间:2007-12-22  
先谢谢tczengjin的回复

我再想了想之前用JDBC时的DAO所做的工作,只是封装了SQL语句。
比如DAO有个insert(User)的方法,封装的是insert into t_user values(?,?,?.....)的操作,Service只要调用DAO的这个insert方法就好了。

可是Hibernate提供了save(user)这样的方法,已经封装了SQL语句,也就是说它已经实现了DAO的功能,没必要再写DAO了。如果为了解耦合,只有写一个Hibernate提供的这些api的抽象,然后如果想切换到JDBC,就另外写一个譬如JDBC的DAO实现。

还是我的菜菜的理解……望指点
0 请登录后投票
论坛首页 Java企业应用版

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