让我们来看一下针对Oracle的DAO设计模式的定义:
使用一个 Data Access Object(DAO)数据访问对象来抽象和归并对数据源的访问。DAO管理与数据源的连接,并且对数据源进行访问和存储。在过去,不管是JDBC或者EJB,都是用DAO来解耦。现在你想想,这难道不是JPA的EntityManager干的事情么?实际上,大多数的JPA DAO都将他们的基础方法委派给EntityMnager。
public void merge(Person person) { em.merge(person); }
所以,对于基本的CRUD的操作,这个观点似乎是正确的,不是吗?不过如果上面的代码片段无法考虑大部分的案例,这将会是个愚蠢的结论。假如Person对象拥有一个Address对象(或者不只一个)呢?在Web应用中,我们并没有所有的对象图表,只有一个需要被合并的Person对象,所以我们不会去合并实体,但是会根据实体的主键去载入实体并更新那些很可能在GUI层被改变的字段。上面的代码片段看起来应该像是这样的:
public Person merge(Person person) { Person original = em.find(Person.class, person.getId()); original.setFirstName(person.getFirstName()); original.setLastName(person.getLastName()); em.flush(); return original; }那么查询呢?如下:
public class PersonService { public List<Person> findByFirstNameAndLastName(String firstName, String lastName) { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<Person> select = builder.createQuery(Person.class); Root<Person> fromPerson = select.from(Person.class); Predicate equalsFirstName = builder.equal(fromPerson.get(Person_.firstName), firstName); Predicate equalsLastName = builder.equal(fromPerson.get(Person_.lastName), lastName); select.where(builder.and(equalsFirstName, equalsLastName)); return em.createQuery(select).getResultList(); } }其它翻译版本 (1) 加载中
ThefindByFirstNameAndLastName()方法很明显地并没有用到任何业务专用语言,只是纯粹的查询语言。在这个案例中,无论采用何种查询策略(JPA-QL或者Criteria),在业务层直接编写这样的代码而且DAO仍然在使用,我认为这不是个明智的做法。
所有这类的例子导致我重新思考DAO在当前的形势状态下是否仍然是必须的。总之,询问这类问题是具有很重要意义的,因为模式易于停滞即使技术的提高使得模式变得有些过时。
其它翻译版本 (1) 加载中 本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务