Dao复杂逻辑SQL

3

我正在开发一个小型业务应用程序,需要知道如何传递复杂的逻辑以指示从数据库获取哪些客户端。

这是我的ClientDAO类:

public class ClientDAO {

    public void save(Client clt) {

    }

    public Client find(int id) {

        return null;
    }

    public void update(Client clt) {

    }

    public void delete(Client clt) {

    }
}

这是一个普通的CRUD类,但如果我需要从日期xx到yy获取所有客户端,我需要添加另一个重载的查找方法吗?如果我想要查找年龄在xx和yy之间的所有客户端,我会再添加一个查找函数吗?这似乎不是一个好的设计。
我知道我正在做错事,我想知道正确的做法。
PS:我将使用没有任何ORM的JDBC。

你打算使用像Hibernate这样的ORM吗? - Matt
不,我只使用JDBC。 - KarimS
1
是的,您需要为每种情况添加一个查找器方法。请记住,这个DAO类仅仅是一个接口,它存在的目的是让用户知道可以通过什么方式查找对象。这并不意味着它的实现会有重复的代码——客户端并不关心,对客户端来说这并不重要。如果有重复的代码,则编写良好的代码以删除它(可能在内部重用一些查找方法),但外部接口必须清晰明了。 - acdcjunior
好的,您可以创建一个接受Client对象的方法。然后,在该方法中,您可以检查该字段是否为空。如果不为空,则为该字段创建where查询... - kucing_terbang
@kucing_terbang 当然,这假设您不需要一个 WHERE column IS NULL 查询。 - Andreas
1个回答

4

当不使用ORM时,创建多个查询数据的方法是正确的做法。DAO的目的是完全将应用程序与数据库访问逻辑隔离开来,这意味着DAO是唯一知道表和列名称的类。

现在,对于高级话题:如果应用程序需要使用各种条件查询表,为每个组合创建一个新方法会很麻烦,而在单个方法上有太多参数也不合适。

对于这种问题,构建器模式 是一个好的解决方案。您的DAO可以实现一个filter()方法,返回一个构建器对象,具有良好的条件方法和最终的execute()方法:

public class ClientDAO {

    public static final class Filter {
        Filter() {
            // code not shown for brevity
        }
        public Filter withNameLike(String name) {
            // code not shown for brevity
        }
        public Filter createdAfter(Date fromDate) {
            // code not shown for brevity
        }
        public Filter createdBefore(Date fromDate) {
            // code not shown for brevity
        }
        public List<Client> query() {
            // code not shown for brevity
        }
    }

    public static Filter filter() {
        return new Filter();
    }

}

然后可以像这样使用:

List<Client> clients = ClientDAO.filter()
                                .withNameLike("%John%")
                                .createdAfter(fromDate)
                                .query();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接