DAO与SERVICE层的疑惑
关键字: DAO SERVICE HIBERNATE在原来EJB项目中,都是使用实体BEAN进行数据持久的,而现在换成了DAO负责持久逻辑,一开始的时候业务层和持久层之间数据通信都是直接使用POJO进行,不再需要像以前使用EJB那样将DTO的数据set到实体BEAN上,减少了很多不必要的代码,刚开始的时候觉得挺爽,可是后来发现一个问题,那就是在service层调用DAO持久一个POJO后,POJO将变成PO,DAO持久方法将会返回一个对象,而我目前的做法就是直接返回一个PO到业务层,可是现在发现这种做法存在不恰当的地方,那就是PO在业务层的话,结果就将业务层与持久层相耦合,而DAO层的作用也因此而消弱,但是如果我不是直接返回PO的话,那我又要构造一个VO返回给业务层,那这种做法不是又回到原来EJB的方式上?而且这样我也无法在业务层上获得HIBERNATE很多优化性能功能,例如lazy load等,看了很多相关的帖子,但是好像都没有我想要的答案,请教一下我该如何解决这个问题?
评论
如果说你问的是层和层间的对象传递的话,dao层可以以返回值的情况给service,然后service里面可以使用ThreadLocal对象,把得到的东西传递到表现层,其实dao->service貌似也可以这样做,不过好象没啥必要哦
对于楼主说的lazy load的问题,可以使用open session in view的解决方案还是可以的,不过我也听有的人说干脆不关闭session,不过我认为这种方法不是很可取,毕竟等待自然释放不是一个很好的选择
你可以把你的Services只注入DAO的一个接口对象呀,同时在前台调用 的时候只要把Services的接口进行简单的注入就可以进行你想要操作啦。
DAO层主要工作访问数据,有这了一层不用关心数据的来源,如果使用HIBERNATE,那么不用关心是直接连数据库,还是从一级缓存还是二级缓存中的数据。
SERVER个人认为是一些业务层的逻辑运算
使用SSH,如果有OPEN SESSION IN VIEW,如果基本是把PO与VO二个概念相对混淆了。特别是VIEW层直接把PO到表现层上去。使用了OPEN SESSION IN VIEW,读数据是根据页面展示所需自动从DAO中获取。对于开发企业业务功能,采用此模式已经足够了。但如果系统是一个超大容量的计算,如运营系统,这样的设计就可能有问题,即分层不清晰而引发各类问题,也不能很好的支持分布式计算。如果表现层就用VO,那么系统可以很好的解藕,因些把OPEN SESSION IN VIEW 去除掉,增加一层DTO,即SERVICE层有DTO的功能,当然这个DTO功能就是因业务需要VO到哪一层的问题,也就是控制对象粒度问题,大部分情况这些都是根据表现层来解定的。如果已有VO不能满足表现层展视的数据,那么在SERVICE层中的DTO就把PO2VO时,把需要的数据给VO。
个人在开发时在struts1时,DTO就要是把PO转成FORM BEAN,但做保存时,把form 转成 vo 通过hiberate session 接口持久成PO。当然当时的项目也主要是普通企业应用。
现在用struts2开发时(webwork),已把form bean概念去掉了,直接把实体bean”作为form bean"这样叫法可能让没有接触过struts2的struts1开发者能够更能理解struts2,因为vo/po都用同一个实体bean,因此通过OPEN SESSION IN VIEW,直接在页面把po数据在页面展示出来。或者把open session in view 不要,把service的po转成vo后在页面展示。
嗯. 不错 这个思路清晰多了 是我明白了不少.
DAO层主要工作访问数据,有这了一层不用关心数据的来源,如果使用HIBERNATE,那么不用关心是直接连数据库,还是从一级缓存还是二级缓存中的数据。
SERVER个人认为是一些业务层的逻辑运算
使用SSH,如果有OPEN SESSION IN VIEW,如果基本是把PO与VO二个概念相对混淆了。特别是VIEW层直接把PO到表现层上去。使用了OPEN SESSION IN VIEW,读数据是根据页面展示所需自动从DAO中获取。对于开发企业业务功能,采用此模式已经足够了。但如果系统是一个超大容量的计算,如运营系统,这样的设计就可能有问题,即分层不清晰而引发各类问题,也不能很好的支持分布式计算。如果表现层就用VO,那么系统可以很好的解藕,因些把OPEN SESSION IN VIEW 去除掉,增加一层DTO,即SERVICE层有DTO的功能,当然这个DTO功能就是因业务需要VO到哪一层的问题,也就是控制对象粒度问题,大部分情况这些都是根据表现层来解定的。如果已有VO不能满足表现层展视的数据,那么在SERVICE层中的DTO就把PO2VO时,把需要的数据给VO。
个人在开发时在struts1时,DTO就要是把PO转成FORM BEAN,但做保存时,把form 转成 vo 通过hiberate session 接口持久成PO。当然当时的项目也主要是普通企业应用。
现在用struts2开发时(webwork),已把form bean概念去掉了,直接把实体bean”作为form bean"这样叫法可能让没有接触过struts2的struts1开发者能够更能理解struts2,因为vo/po都用同一个实体bean,因此通过OPEN SESSION IN VIEW,直接在页面把po数据在页面展示出来。或者把open session in view 不要,把service的po转成vo后在页面展示。
Exactly as you did. If put it in EJB language,they are "Session Bean" implementing busines logic, and "Entity Bean" representing data.
这种做法和以前EJB的做法确实没什么太大的区别,说实话,我目前也只适应这种方式,真要叫我完全OO,然后全部充血模型,我头都会大,我觉得那样就太过教条了,而且很容易出现问题,要求太高了,反而我觉得这种facade的方式我更喜欢,也更适合目前的项目。
For me,"domain objects" is a type of POJOs that only has data,almost no business logic. Another type of POJOs contains business logic,for example,"stateless beans" in EJB3 or Java Bean in Spring.
As for "暴露了领域对象,很容易造成混乱",I think "domain objects" should be transparent and shared by all the layers. In contrast,the POJOs that implement the business logic should be confined to its boundary,by adding interface.
JPA is not designed to replace DAO, they are different concept. Put it in another way, using JPA will make the DAO layer seem to be redundant if it is a small system.
那你所谓的another type of POJOS 和 only has data 的POJO是什么关系呢?包含、继承还是一个包含业务逻辑的service实现?我目前的实现就是POJO包含数据以及少部分与持久无关的逻辑即贫血模型,再做一个service做具体的业务逻辑。
For me,"domain objects" is a type of POJOs that only has data,almost no business logic. Another type of POJOs contains business logic,for example,"stateless beans" in EJB3 or Java Bean in Spring.
As for "暴露了领域对象,很容易造成混乱",I think "domain objects" should be transparent and shared by all the layers. In contrast,the POJOs that implement the business logic should be confined to its boundary,by adding interface.
JPA is not designed to replace DAO, they are different concept. Put it in another way, using JPA will make the DAO layer seem to be redundant if it is a small system.
When using SSH(Struts+Spring+Hibernate), data transform and transfer is painful, usually, from ActionForm(Web) --> VO(Service) --> PO(DAO) .... -->
However, that is the cost of layering your application, which makes your system more flexible and loosely coupled.
The problem is when using the above architectures, there is too much duplication of classes and its “getter and setter” and too much simple “copy” of code. For system maintenance and extension, it’s a nightmare.
So I would say your problem is not only about passing data from service layer into DAO layer, but also about transferring data between different layers in system.
The solution probably is using POJO and new web frameworks and new Persistence APIs.
If you want to continue to use Struts and Spring, using Struts2+spring+JPA is your choice. If you are going to adopt EJB, using JSF+EJB3 is your choice. The key of both architectures is their using POJO(+Annotation) as the vehicle of data transfer and manipulation.
For example, JSF components can be directly bound to POJO’s field; JPA EntityManager uses POJO+Annotion as Entity Bean to manipulate data in database. Struts2 also discarded the ActionForm and uses POJO as HTML input or output value binding.
Anyway, you may still worry about using one single POJO in every layers; it probably makes the system tightly coupled. But in fact it does not. You have to change the way you regard the “domain objects”(POJO+Annotation), that move between different layers of the system,carring data, being presented, changed, saved into database, etc. These “domain objects” are the blood of the system, and can be used by Web Framework, Business Logic code, Persistence API. These “domain objects” almost only contain data and its getters and setters, or some small logic for conversion of data. They are the only artifacts created, used, changed, transferred by the components in every layers in the system.
Another issue is DAO layer seems to disappear. Yes, if you use JPA, write another layer of DAO seems to be meaningless. In my point of view, DAO is only useful when you use JDBC or a very big system with multi-layer even in business logic code. If you has already use ORM tool such as Hibernate, JPA, it really doesn’t give much benefit for the system, unless it’s a very big system.
I hope this will give you little help.
我并不是用hibernate来优化业务逻辑层,只是我在用到hibernate的时候,我必然要考虑性能这方面的因素,hibernate是ORM,但不代表不考虑它的性能,你这种说法有点过于偏激。
使用open session inview,把事务从dao层扩大到了业务层,在业务层po虽然可以访问持久层,但这是透明的,并没有对你的业务层代码有什么侵蚀。如果不用hibernate,用其他持久化技术,这个po将会是一个完整的对象。整个业务层接口和代码不会有什么改变。
使用open session in view不是把事务扩大到业务层,而是扩大到了表现层,这中间存在的问题就不多说了,还有从代码上来看确实是没有依赖于hibernate的地方,但是实际上还是依赖了,举个例子,一个update的方法,在业务层直接通过session缓存load到一个对象,然后通过set方法把值改变,因为缓存于session,我们不需要在最后加多一个dao.update(obj);就可以自动保存,这段代码在hibernate行得通,可是如果DAO实现用JDBC或者其他的框架实现呢?我们就要在那些没有这一特性或者有这一特性但是方式不一样的实现上改动业务层的代码,虽然代码上来看是透明的,但是实际还是会有依赖,这种依赖我自己称之为透明依赖,因为透明,也比较难察觉到。
不过这个问题在现在来说也不是什么太大的问题,我还是认为最重要不要太过复杂,能简单就尽量简单明了,层次分明就好。太过于在意反而会导致过度设计,带来不必要的复杂性,简单就是美,呵呵。
使用open session inview,把事务从dao层扩大到了业务层,在业务层po虽然可以访问持久层,但这是透明的,并没有对你的业务层代码有什么侵蚀。如果不用hibernate,用其他持久化技术,这个po将会是一个完整的对象。整个业务层接口和代码不会有什么改变。
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 109547 次
- 性别:

- 来自: 珠海

- 详细资料
搜索本博客
我的相册
共 9 张
最新评论
-
使用wubi安装ubuntu记得绕 ...
好象也是这个问题,我今天也搞了一天了。不要用wubi.exe,去下载对应的wub ...
-- by feiyelanghai -
你的价值在哪里?
不同的心态决定着截然不同的结果。这有点像传说中的境界了吧。
-- by pubx -
你的价值在哪里?
两个字 —心态
-- by flysnail -
你的价值在哪里?
同感,就看自己怎么去看待,同样一件事情,不同的心态有着不同的结果。
-- by yuanqixun -
你的价值在哪里?
8) 不得不让我想起啊Q
-- by icefire






评论排行榜