10

我已经看到并使用过很多旧的、基于 JDBC 的 DAO 代码,这些代码通常从 CRUD 方法开始。我的问题特别与检索方法或“发现者”有关。通常,我发现 DAO 以两种方法开始:

  • 查找并返回所有
  • 根据唯一标识符检索特定实例

通常,这两个发现者是不够的。我通常最终会看到一个 DAO 类被反复修改以添加 finder 方法,如下所示:

  • 查找并返回 ALL where {condition}

发生的情况是,当需要支持新的 {conditions} 或修改现有方法以添加新参数作为标志以修改方法内部的 SQL 查询以支持附加条件时,会添加更多方法。

这是一种丑陋的方法,违反了开闭原则。每当需要支持一些新的检索条件时,看到 DAO 类不断修改,这一直是我的烦恼。对这个问题的研究经常将我指向存储库模式并将检索条件封装为规范或查询对象,然后将它们传递给查找器方法。但这似乎只有在您拥有整个数据集的内存集合或使用某种 ORM 时才可行(我正在使用较旧的 JDBC 代码)

我考虑过一种解决方案,该解决方案将 DAO 管理的整个数据集作为内存中的集合延迟加载,然后使用规范模式作为检索查询。然后我在集合上实现某种观察者,它在调用创建、更新或删除方法时只更新数据库。但显然性能和可扩展性会受到严重影响。

对此有什么想法吗?


感谢您到目前为止的回复。我确实有一个想法——您对使用命令/策略模式来封装数据访问请求有何看法?每个单独的具体命令可以代表一种特定类型的访问,并且可以传递给调用者。我最终会得到许多具体命令类,但每个类都将只关注一种访问,并且应该非常可测试和隔离。

    public abstract class Command<R>{
       public <R> execute();
       public void setArguments(CommandArguments args){
          //store arguments  
       }
    }

    //map based structure for storing and returning arguments
    public class CommandArguments{
         public String getAsString(String key);
         public String getAsInt(String key);
         //... others
    }

    //In some business class...
    Command command = CommandFactory.create("SearchByName");
    CommandArguments args = new CommandArguments();
    args.setValue("name", name);
    // others
    command.setArguments(args);
    List<Customer> list  = command.execute();
4

2 回答 2

4

我们已经将 iBatis 用于我们的数据层 ORM,并且已经能够通过传递带有您可能希望用作参数的各种字段的参数对象来实现您在一个查询中提出的建议。

然后在 WHERE 子句中,您可以将每个字段指定为条件子句,但前提是它填充在参数对象中。如果参数 obj 中只有一个字段不为空,则它是唯一用于过滤结果的字段。

因此,如果您需要向参数添加字段,您只需更改 SQL 和 paramObj。然后,您可以有 2 个方法返回 ALL 或基于传递的参数组合的子集,或者至少这种方法会减少所需的查询数量。

例如,类似于...的东西

SELECT * FROM MY_TABLE
WHERE FIELD_ZERO = paramObj.field0
<isNotNull property="paramObj.field1">AND FIELD_ONE = paramObj.field1</isNotNull>
<isNotNull property="paramObj.field2">AND FIELD_TWO = paramObj.field2</isNotNull>
<isNotNull property="paramObj.field3">AND FIELD_THREE = paramObj.field3</isNotNull>
于 2011-02-18T03:47:19.023 回答
0

与其在每个可能的条件变得明显时为它们创建特定的查找器方法,不如创建一个通用的查找器 API?这可以采用具有内部枚举来表示字段的 DAO 的形式,以及采用 DAO 内部类的实例列表的方法,其中字段表示要过滤的 DAO 的哪个字段,要对其应用什么过滤器,以及什么条件(AND、OR 等)。

设置起来需要一些工作,对于小型项目来说可能有点矫枉过正,但它肯定是可行的。ORM 框架通常已经内置了类似的东西,因此您可能需要考虑采用其中一种(或者至少在设计您自己的解决方案以改造您的遗留应用程序时查看它们是如何实现它的)。

于 2011-02-17T08:29:12.277 回答