如何将哪些方法实现到“正确”的DAO类中?

3

我知道这个问题的标题不是很描述性,但我不知道如何更好地解释这个问题...

我想知道您对DAO类实现过程中出现的疑问的看法。

我正在实现一个CustomerDAO类,它必须提供对应用程序数据库中相关数据的访问。我已经像往常一样实现了经典的CRUD方法,但现在我需要实现一些提供使用“特定”查询检索到的数据的方法。

我的意思是:

SELECT [...] FROM CUSTOMERS WHERE <CUSTOMER_PROPERTY_1> = 'X' AND <CUSTOMER_SOME_DATE> > ? AND <CUSTOMER_SOME_DATE> < ?

所以我的问题是,应该采取什么样的方法或者“最佳实践”呢?是要实现许多特定的方法,比如getCustomersByXPropertyBetweenDates(),还是尝试推广查询并实现一个更加“通用”的(不是Java的意义上)方法呢?
请注意,我正在使用纯JDBC和Spring Framework v3.1提供的JdbcTemplate

你考虑过使用命名查询吗? - RP-
@Rp- 使用命名查询的实际优势是什么?我能在JDBC中使用它们吗? - davioooh
@davioooh 不行,这对这个问题不适用(Spring 和 jdbcTemplate),它们用于 JPA 和 Hibernate 等,允许在域对象上定义查询。在我看来有点被高估了。 - NimChimpsky
1
我认为,DAO层的存在之所以有意义,就是要“具体化” - 它是一层可以明确指定如何有意义地访问(包括查找或查询)数据的层。您希望通过使用更简单的API来替换编写SQL的复杂性,而不是使用不同的复杂(-ish)通用API来隐藏它。 - millimoose
@Inerdial 是的,我完全同意你的观点,所以我会实现“特定”的方法。非常感谢您有趣的评论! - davioooh
3个回答

1
你如何使你列出的查询“通用”?另外,选择词不好。
我只会将单独的查询分开。不要试图做任何聪明的事情,你有一个特定的查询,保持简单,不要试图适应另一个查询。
如果你想要真正通用,我建议使用ORM。

由于在这个问题中解释的原因,我不能使用ORM。当我说“通用”时,我的意思是一个更一般化(也许仍然是一个糟糕的选择)的查询...因此,实现的方法可以更具可重用性...希望这足够清楚了... - davioooh
@davioooh 哦,我的天啊,那个链接让我毛骨悚然,我认为那很糟糕。你想要的很清楚,但是如何编写代码使你列出的查询适合更通用的形式?我的观点是,除非付出大量的工作,否则你无法做到这一点。为了什么收益?除非真的很简单使它们“适合”,否则只需保持查询分开即可。 - NimChimpsky
1
所以我认为我会选择几种特定的方法。试图实现通用方法可能只会让事情变得复杂,获得一些“内部平台效应”,你同意我的看法吗? - davioooh
是的。最近我不得不回到这种dao层(而不是ORM),它实际上非常好用。简单,一切都在你期望的地方,没有其他依赖,简单的SQL - 没有使用长if语句创建SQL where子句。 - NimChimpsky

0

我认为这是更多基于业务的决策。如果您有针对不同方法的单独业务操作,可以创建特定的方法。如果您拥有“高级搜索表单”业务操作,并且有一组用于搜索条件的字段,那么创建一个特殊的“查询”实体类来存储表单数据,然后由DAO实现将其转换为SQL查询语句,这样做更有意义。

此外,请查看查询 DSL,它可能会简化DAO层的很多工作。


0

实现一个抽象的DAO类,该类定义/实现了所有DAO通用(CRUD)方法。在特定的DAO接口中定义业务方法,并在DAO类中实现。

public interface IDAO< T extends Serializable>{

   T save( final T entity );
   T update( final T entity);
   void delete( final long id );
   void deleteAll();
   T findOne( final long id );
   List< T > findAll();

}

public abstract class AbstractDAO< T extends Serializable > implements IDAO< T >{




protected abstract JdbcTemplate getTemplate();


protected abstract T save(T entity);

    ...

}

客户DAO接口将定义业务特定的方法

public interface ICustomerDAO extends IDAO<Customer>
{
   public List<Customer> findDormantCustomers();

}

客户DAO实现将是以下的样子。

public class CustomerDAO extends AbstractDAO<Customer> implements ICustomerDAO{

public Customer save(Customer customer){
   getTemplate().insert(...);
   return customer;
}

    public List<Customer> findDormantCustomers(){
       ...
       return;
    }
}

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