【问题标题】:How to design interfaces for complex query in DAO(Should we always design generic interfaces for DAO)?如何为DAO中的复杂查询设计接口(我们是否应该总是为DAO设计通用接口)?
【发布时间】:2014-10-21 18:01:02
【问题描述】:

当我第一次学习编码时,我被告知要为 DAO 编写通用接口。不建议设计“findByName”之类的接口,因为 findByName 与业务逻辑(名称)相关。我使用hibernate的Criteria来编写通用接口,效果很好。最近在使用mybatis,但是接口的通用性很难保持,因为我必须自己写sql。我写了很多这样的方法:

T find(QueryTuple queryTuple);

public class QueryTuple {
    private String key;
    private Object value;
    //This is an enum
    private CompareOperqator operator;
    // setter and getter
}

我这样调用 find 方法:

find(new QueryTuple("name", "tom", CompareOperqator.EQUAL));
find(new QueryTuple("gender", "m", CompareOperqator.EQUAL));

但是如果我想写一些复杂的查询,我不能保持接口那么“通用”,我必须写findByXXAndXX这样的接口。

保持所谓的“通用”真的好吗?我发现Spring数据也支持findByXX这样的接口。

【问题讨论】:

  • mybatis API 已经是一个通用的 DAO:它允许您定义任何类型的查询并执行它。 DAO 的重点是非泛型,并将查询创建逻辑封装到功能性可重用方法中。

标签: java dao mybatis


【解决方案1】:

有人告诉我为 DAO 编写通用接口

IMO,你不应该重新发明轮子,这样的事情都已经实现了。

但是,如果您愿意,请使用Builder pattern。它可能看起来像这样:

dao.query("person").with("name", "tom").with("gender", "m").find();

请注意,我不传递 QueryTuple 的实例,而只是传递构造这些实例的参数。而且它不是类型安全的,只是最简单的实现。

with() 方法可以默认为CompareOperator.EQUAL 并忽略大小写,并且还应该有一个带有第三和第四个参数的版本:

public QueryBuilder with(String property, String value) {
    return with(property, value, CompareOperator.EQUAL, true);
}

public QueryBuilder with(String property, String value, 
                         CompareOperator compareOperator, 
                         boolean ignoreCase) {
    ...
}

【讨论】:

  • 感谢您的回答,构建模式是更好的方法!你也认为接口应该是通用的,但你怎么看Spring-data-jpa? Spring data jpa 支持“findByEmailAddressAndLastname”之类的接口,“EmailAddressAndLastname”是否通用?所以我徘徊哪个更好。
【解决方案2】:

它是 MBG(mybatis 生成器)。就像@scriptin 说的那样,我重新发明了一个轮子。使用 xxxByExample 非常方便,如果需要也很容易扩展!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2011-03-07
    相关资源
    最近更新 更多