论坛首页 Java企业应用论坛

关于Dao设计的典型问题

浏览 11628 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-01-02  
DAO
本人最近在开发一个SSH架构的项目,是按照action-service-dao的逻辑层次进行设计的,现在在service和dao层的设计上遇到了一些问题,还请。

问题是这样的:
由于业务需要,会使用到组合查询情况,这些组合查询情况是根据域对象的不同状态进行组合的,比如说一个bug管理业务,需要得到某个user当前可看到的bug列表,会根据user的角色,组合查询不同状态以及不同的创建者、修改者条件,当然这其中还存在一个用户拥有多个角色的情况,这时就需要把不同角色的查询条件用“或”的方式再组合。

对于用户查询条件的组合,本人以为属于业务逻辑,所以应该放在service层中进行,而根据组合条件进行查询,则属于直接的数据库操作,则应该放在dao层去实现。但是如果在service层直接组合成hibernate的Hql语句或Criteria条件,则使Dao层会依赖于hibernate,以后替换不同的dao实现会有问题。所以只能是为查询再创建一个表达式类,然后Dao接口直接以表达式对象为参数,在Hibernate的Dao实现内部根据表达式组合成Hibernate的Hql或Criteria条件。但是这样发现会增加表达式设计方面的额外工作量,使用Hibernate的提供的复合查询条件的优势将会被抵消。

请一下,我这样设计是否合理,有没有其他好的方法。
   发表时间:2007-01-02  
mrshan 写道

问题是这样的:
由于业务需要,会使用到组合查询情况,这些组合查询情况是根据域对象的不同状态进行组合的,比如说一个bug管理业务,需要得到某个user当前可看到的bug列表,会根据user的角色,组合查询不同状态以及不同的创建者、修改者条件,当然这其中还存在一个用户拥有多个角色的情况,这时就需要把不同角色的查询条件用“或”的方式再组合。

这个要看你的系统如何界定权限的边界,我个人觉得这属于权限的范围,不要硬编码在业务逻辑中。
mrshan 写道

对于用户查询条件的组合,本人以为属于业务逻辑,所以应该放在service层中进行,而根据组合条件进行查询,则属于直接的数据库操作,则应该放在dao层去实现。但是如果在service层直接组合成hibernate的Hql语句或Criteria条件,则使Dao层会依赖于hibernate,以后替换不同的dao实现会有问题。所以只能是为查询再创建一个表达式类,然后Dao接口直接以表达式对象为参数,在Hibernate的Dao实现内部根据表达式组合成Hibernate的Hql或Criteria条件。但是这样发现会增加表达式设计方面的额外工作量,使用Hibernate的提供的复合查询条件的优势将会被抵消。

从设计角度来说自己写一个fileterMap或者其他的东西来充当service到dao的桥梁不错,可以避免hibernate对service的侵入。但是从实际项目的角度来看,这个问题的关键是以后会不会有变化的需求。如果真的有可能替换hibernate那么就如你所说,如果不可能的话直接从action传detachedcriteria也未尝不可,可以有效的提高开发效率。
0 请登录后投票
   发表时间:2007-01-02  
从你的描述中可以看出,你的系统中一个user 可以拥有多个role.
一个user能看到的记录由他的role决定的。DAO始终是根据给定的role或则roles去查询可以看到的记录,这样抽象一下,是否就不存在这个问题呢?
0 请登录后投票
   发表时间:2007-01-02  
service不应该知道dao是用hibernate或者还是ibatis实现的(或者其他),比较好的做法就是map,key保存condition,value保存查询的值,然后传到dao中,用通用的方法来解析这个map,然后设置给query进行查询(或者设值给example也行,也可以直接设值给Restrictions).
0 请登录后投票
   发表时间:2007-01-02  
应该有一个权限表,里面有每个Role和Resource(资源)的对应关系,有这种关系才能通过看到,没有则看不到。每次查询之前先把这个用户的Role查出来,然后查出这个Role所对应的可以取用的资源,这样就能限制访问了。
0 请登录后投票
   发表时间:2007-01-02  
geradle 写道
引用
一个user能看到的记录由他的role决定的。DAO始终是根据给定的role或则roles去查询可以看到的记录,这样抽象一下,是否就不存在这个问题呢?

我不明白你说的抽象是怎样抽象,能否具体说明一下?你的意思是在dao层的接口中用role作为查询参数吗?如果那样dao中照样还要包含组合查询条件的逻辑。

ahuaxuan 写道
引用
service不应该知道dao是用hibernate或者还是ibatis实现的(或者其他),比较好的做法就是map,key保存condition,value保存查询的值,然后传到dao中,用通用的方法来解析这个map,然后设置给query进行查询(或者设值给example也行,也可以直接设值给Restrictions).

这种方式我也想过,可是对于复杂条件的组合情况呢?比如说有“大于”“小于”“like”等等多种情况组合,map就不够用了。

刑天战士 写道
引用
应该有一个权限表,里面有每个Role和Resource(资源)的对应关系,有这种关系才能通过看到,没有则看不到。每次查询之前先把这个用户的Role查出来,然后查出这个Role所对应的可以取用的资源,这样就能限制访问了。

请详细说明一下资源里包括什么东东好吗?
0 请登录后投票
   发表时间:2007-01-02  
Resource应该是一张表,对应的类要看你的需求,有一个公共的父类Resource,然后下面有子类(UrlResource,FileResource)等等,用单表继承来实现,在写Sql的时候用IN判断一下。这张表里面有ID(废话),资源的名称,最重要的是资源的路径(反正就是能得到资源的东东)。这个只是我在我们公司的滥框架基础上自己YY的,我不懂Hibernate,可能有出入,你自己结合大家的意见好好考虑一下吧
0 请登录后投票
   发表时间:2007-01-03  
我也做过类似的工作:创建表达式类,然后组合查询条件,其目的是为了应付可能的需求变更,但是组合查询条件的时候,感觉就像重写SQL语法解析工具,容易出错不说,总有一些地方会考虑不到,毕竟,还是水平有限啊。
从逻辑上来说,对于这样的查询,我最习惯的还是直接使用SQL语句到数据库上查,基本上一条SQL语句就可以应付大部分查询需求,复杂一点的,用2~3条也能基本搞定。对于这个问题,我倾向于使用ibatis解决,service层弄的很薄,基本上就是个封装,来一类查询需求就写一个接口方法,从service层写起。这样一个好处是快,容易验证,而且事先不用考虑太多,反正有SQL语句顶着,没什么做不了的,坏处是如果需求千奇百怪,service会弄得很大,很乱,自己看着都烦。
至于修改数据库表的设计,也曾经考虑过,但是没找到处理组合查询的方法,就放弃了,现在想想,对这个思路,或许放弃的有些早了。

其实,我也很困惑于这个问题,不知道哪位牛人能够指点一二。

我现在的设计思路是:只要简单,容易理解,代码丑点就丑点吧,等到实在不能忍了再打扮。
0 请登录后投票
   发表时间:2007-01-03  
members,bugs,rights这三项关系在hbm.xml文件中应该先设定好,bugs,rights对members应该是多对一的关系,以members为核心进行查询,而不是做三个分离和不相干的表设计,这实际上是把现实中三者的紧密联系在代码里人为割裂了.
0 请登录后投票
   发表时间:2007-01-03  
mrshan 写道
geradle 写道
引用
一个user能看到的记录由他的role决定的。DAO始终是根据给定的role或则roles去查询可以看到的记录,这样抽象一下,是否就不存在这个问题呢?

我不明白你说的抽象是怎样抽象,能否具体说明一下?你的意思是在dao层的接口中用role作为查询参数吗?如果那样dao中照样还要包含组合查询条件的逻辑。

嗯,我初步是这样想的,但是考虑到,可能有些问题不仅仅和Role相关,所以单纯传role做为查询参数似乎不能全部解决。
如果把role做为参数传递的话,那么一个user具有多个role的这个逻辑,应该放到service里面吧。
0 请登录后投票
论坛首页 Java企业应用版

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