锁定老帖子 主题:关于Dao设计的典型问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-01-02
问题是这样的: 由于业务需要,会使用到组合查询情况,这些组合查询情况是根据域对象的不同状态进行组合的,比如说一个bug管理业务,需要得到某个user当前可看到的bug列表,会根据user的角色,组合查询不同状态以及不同的创建者、修改者条件,当然这其中还存在一个用户拥有多个角色的情况,这时就需要把不同角色的查询条件用“或”的方式再组合。 对于用户查询条件的组合,本人以为属于业务逻辑,所以应该放在service层中进行,而根据组合条件进行查询,则属于直接的数据库操作,则应该放在dao层去实现。但是如果在service层直接组合成hibernate的Hql语句或Criteria条件,则使Dao层会依赖于hibernate,以后替换不同的dao实现会有问题。所以只能是为查询再创建一个表达式类,然后Dao接口直接以表达式对象为参数,在Hibernate的Dao实现内部根据表达式组合成Hibernate的Hql或Criteria条件。但是这样发现会增加表达式设计方面的额外工作量,使用Hibernate的提供的复合查询条件的优势将会被抵消。 请一下,我这样设计是否合理,有没有其他好的方法。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间: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也未尝不可,可以有效的提高开发效率。 |
|
返回顶楼 | |
发表时间:2007-01-02
从你的描述中可以看出,你的系统中一个user 可以拥有多个role.
一个user能看到的记录由他的role决定的。DAO始终是根据给定的role或则roles去查询可以看到的记录,这样抽象一下,是否就不存在这个问题呢? |
|
返回顶楼 | |
发表时间:2007-01-02
service不应该知道dao是用hibernate或者还是ibatis实现的(或者其他),比较好的做法就是map,key保存condition,value保存查询的值,然后传到dao中,用通用的方法来解析这个map,然后设置给query进行查询(或者设值给example也行,也可以直接设值给Restrictions).
|
|
返回顶楼 | |
发表时间:2007-01-02
应该有一个权限表,里面有每个Role和Resource(资源)的对应关系,有这种关系才能通过看到,没有则看不到。每次查询之前先把这个用户的Role查出来,然后查出这个Role所对应的可以取用的资源,这样就能限制访问了。
|
|
返回顶楼 | |
发表时间: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所对应的可以取用的资源,这样就能限制访问了。
请详细说明一下资源里包括什么东东好吗? |
|
返回顶楼 | |
发表时间:2007-01-02
Resource应该是一张表,对应的类要看你的需求,有一个公共的父类Resource,然后下面有子类(UrlResource,FileResource)等等,用单表继承来实现,在写Sql的时候用IN判断一下。这张表里面有ID(废话),资源的名称,最重要的是资源的路径(反正就是能得到资源的东东)。这个只是我在我们公司的滥框架基础上自己YY的,我不懂Hibernate,可能有出入,你自己结合大家的意见好好考虑一下吧
|
|
返回顶楼 | |
发表时间:2007-01-03
我也做过类似的工作:创建表达式类,然后组合查询条件,其目的是为了应付可能的需求变更,但是组合查询条件的时候,感觉就像重写SQL语法解析工具,容易出错不说,总有一些地方会考虑不到,毕竟,还是水平有限啊。
从逻辑上来说,对于这样的查询,我最习惯的还是直接使用SQL语句到数据库上查,基本上一条SQL语句就可以应付大部分查询需求,复杂一点的,用2~3条也能基本搞定。对于这个问题,我倾向于使用ibatis解决,service层弄的很薄,基本上就是个封装,来一类查询需求就写一个接口方法,从service层写起。这样一个好处是快,容易验证,而且事先不用考虑太多,反正有SQL语句顶着,没什么做不了的,坏处是如果需求千奇百怪,service会弄得很大,很乱,自己看着都烦。 至于修改数据库表的设计,也曾经考虑过,但是没找到处理组合查询的方法,就放弃了,现在想想,对这个思路,或许放弃的有些早了。 其实,我也很困惑于这个问题,不知道哪位牛人能够指点一二。 我现在的设计思路是:只要简单,容易理解,代码丑点就丑点吧,等到实在不能忍了再打扮。 |
|
返回顶楼 | |
发表时间:2007-01-03
members,bugs,rights这三项关系在hbm.xml文件中应该先设定好,bugs,rights对members应该是多对一的关系,以members为核心进行查询,而不是做三个分离和不相干的表设计,这实际上是把现实中三者的紧密联系在代码里人为割裂了.
|
|
返回顶楼 | |
发表时间:2007-01-03
mrshan 写道 geradle 写道
引用 一个user能看到的记录由他的role决定的。DAO始终是根据给定的role或则roles去查询可以看到的记录,这样抽象一下,是否就不存在这个问题呢?
我不明白你说的抽象是怎样抽象,能否具体说明一下?你的意思是在dao层的接口中用role作为查询参数吗?如果那样dao中照样还要包含组合查询条件的逻辑。 嗯,我初步是这样想的,但是考虑到,可能有些问题不仅仅和Role相关,所以单纯传role做为查询参数似乎不能全部解决。 如果把role做为参数传递的话,那么一个user具有多个role的这个逻辑,应该放到service里面吧。 |
|
返回顶楼 | |