通用查询对象最优经验

来源:互联网 发布:php开源论坛系统 编辑:程序博客网 时间:2024/05/17 07:07

最近正在研究DAO,准备做一个批量查询框架,于是就到TSS上找,下面是一片不错的文章可以参考:

原文:http://www.theserverside.com/patterns/thread.tss?thread_id=29319

问题:使用数据访问对象(Data Access ObjectsDAO)读取数据会产生一些影响设计和开发的问题。

1.  系统中存在大量的DAO类。一个系统拥有数以百计的实体和数据表,需要大量的DAO类,每一个里面只有少量的方法,而它们的实现和测试都是十分相似的。
[
译者:]我曾经做过一个中等规模的项目,大约有50多个business logic用例,40多个批量查询,由于遵循共同的接口,它们的结构一模一样。现在想来,确实是包含很多重复劳动。

2.  与其他使用Session Bean实现的商业逻辑矛盾。遵循某种规则的数据查询也是一种商业逻辑,它们理应与其他商业模块具有相同的结构。但是DAO模式导致这种数据读取逻辑与其他商业逻辑相分离,从而产生不完整的Façade层,而这是一种不合理的设计(Design Fault)。
[
译者:]对于某些情况,这样的设计无可厚非,例如用户注册和注册用户查询,由于不属于一个用例,所以它们采用不同的结构并没有什么不对。但是有些数据,例如批量修改某些用户的状态,由于查询和修改是一个用例流的不同部分,所以应该遵循相同的结构。

3.  虽然DAO对象也实现一些商业逻辑,但是它们更专著于实现那些与持久层相关的非商业逻辑,例如:排序、分页、分组等。DAO对象需要知道如何准备数据,所以你必须考虑让DAO的实现者了解有关持久性的所有细节。这种设计破坏了逻辑层的完整性,所以也是一种设计缺陷。
[
译者:]虽然使用Hibernate可避免上述情况,但是我更加希望我的应用只依赖权威性的框架。当然,在EJB3正式推出之前我仍然会使用Hibernate,因为它确实好。

4.  没有任何声明式的安全机制可以支持DAO,而你的其他的业务逻辑却可以使用EJB的安全性。
[
译者:]这应该是JOPOs实现DAO的硬伤,不过可以用Session Bean实现DAO呀(又要再加几十个EJB)。再说,声明式安全性很不灵活,还不如不用。

解决:

实现一个“Query”对象,用于创建SQL查询并动态的组合各种参数,形成WHERE CLAUSE,最后再执行这些查询。这个Query对象使用普通查询引擎(Generic Query Engine)来管理和运行SQL statement,并返回执行结果。这些结果可以是ResultSet,也可以是ValueObject的集合或其他任何你需要的格式。

现在,所有的DAO对象都可以被一个返回Query对象的Session Bean方法所替代。用于读操作的商业方法返回一个符合业务规则的Query对象——Query对象是一个serializable object。然后,客户端调用Query的一个类似于“execute”的方法取得查询结果。SQLClient层执行,因此JDBC Connection也是在这个时候创建。这里没有任何数据在Session BeanClient层之间传递,取而代之的是一个叫做“Query”的Java Bean

[译者:]也就是说,Query对象是持久层逻辑的一部分。

这种方法允许业务逻辑和持久逻辑相分离。当Session Bean创建Query Object的时候,它只是使用了业务逻辑的各种参数而不知道数据如何展示。当客户端——presentation layer——得到了这个Query,就可以对它附加各种持久性规则,诸如排序、分页等。这些操作可以使用Query对象的其他API实现,这些API使用Query Engine处理各种参数。[译者:]原文的意思是说Query Engine可以动态的处理查询参数,把它们组合成WHERE子句,并附加在原始的SQL Statement上。

好的SQL Engine可以更加灵活的处理各种查询参数。它需要了解SQL语法,并动态创建各种不同的queries

好处:

具有所有DAO的优点。

再不需要开发DAO类。

具有完整的包含查询操作的业务逻辑层。

更好的在层间分离查询逻辑,举例来说,持久性规则的影响只在持久层施加。

用于读取得业务方法只包含很少的实现代码,因为QueryQuery Engine已经实现了大多数功能。

原创粉丝点击