VB_*_*VB_ 5 java spring dao design-patterns repository
在“ 不要使用DAO,使用存储库”一文中,对DAO和存储库模式之间的区别有很好的解释。
我的简短复述-DAO使我们能够使用多种方法来膨胀界面,从而阻碍了更改和测试。反过来,存储库使用query方法封装所有接受自定义/更改的方法,这些方法接受Specification作为参数。当您需要在存储库中进行新操作时-请勿更改它,而应创建一个新的继承人Specification。
我的结论-存储库模式比DAO更好,因为它的接口禁止修改。
我到目前为止正确吗?我是否没有错过存储库模式的某些好处?
但是,如果您查看Spring的访问数据JPA指南,则会找到以下代码:
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName); //each time you need custom behavior you need to add a method
//...
}
Run Code Online (Sandbox Code Playgroud)
它与上一篇文章不冲突吗?为什么Spring的存储库迫使我们添加新的接口方法?
\n\n\n我的结论 - 存储库模式比 DAO 更好,因为它的\n 接口无法修改
\n
这取决于...
\n因为存储库模式更复杂,因为它需要编写更多代码,并且对于存储库客户端及其实现来说,比 DAO 模式具有更高的抽象级别。
\n当您需要在查询中具有灵活性和/或查询在结果中混合多个实体时,存储库模式可以满足这些需求。\n如果您需要在表上进行主要简单的增删改查操作(基本创建、读取、更新和删除操作),我认为使用真正的存储库(因此具有规范)可能是一种开销。
\n\n\n但是,如果您查看 Spring 的访问数据 JPA 指南,您会发现以下代码:
\n
public interface CustomerRepository extends CrudRepository<Customer,Long> {\n List<Customer> findByLastName(String lastName); //each time you need custom behavior you need to add a method\n //... }\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n这和上一篇文章不冲突吗?为什么 Spring 的存储库强制我们向接口添加新方法?
\n
是的。我认为问题来自于 Spring,它使用一个流行术语(存储库)来代表一个类,该类不是根据模式文献的存储库。( http://martinfowler.com/eaaCatalog/repository.html ) \n
\n我认为你应该将 Spring Repository 视为 DAO,因为 Spring 存储库的基本功能接口是 CrudRepository。从本质上讲,CRUD 操作是我们在 DAO 中找到的操作......
之后,没有什么可以阻止您丰富存储库以提供符合 Spring 规范的存储库方法,如Spring data官方文档的 2.4 点所示。\nSpring 建议您像示例中那样
扩展接口。org.springframework.data.repository.CrudRepository这是更简单的方法,我想这是最常见的方法......
public interface CustomerRepository extends CrudRepository<Customer, Long>, JpaSpecificationExecutor {\n \xe2\x80\xa6\n}\nRun Code Online (Sandbox Code Playgroud)\n\n并JpaSpecificationExecutor提供使用规范的方法,从而促进减少查询源代码中的重复处理:
/*\n * Copyright 2008-2011 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.springframework.data.jpa.repository;\n\nimport java.util.List;\n\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.domain.Sort;\nimport org.springframework.data.jpa.domain.Specification;\n\n/**\n * Interface to allow execution of {@link Specification}s based on the JPA criteria API.\n * \n * @author Oliver Gierke\n */\npublic interface JpaSpecificationExecutor<T> {\n\n /**\n * Returns a single entity matching the given {@link Specification}.\n * \n * @param spec\n * @return\n */\n T findOne(Specification<T> spec);\n\n /**\n * Returns all entities matching the given {@link Specification}.\n * \n * @param spec\n * @return\n */\n List<T> findAll(Specification<T> spec);\n\n /**\n * Returns a {@link Page} of entities matching the given {@link Specification}.\n * \n * @param spec\n * @param pageable\n * @return\n */\n Page<T> findAll(Specification<T> spec, Pageable pageable);\n\n /**\n * Returns all entities matching the given {@link Specification} and {@link Sort}.\n * \n * @param spec\n * @param sort\n * @return\n */\n List<T> findAll(Specification<T> spec, Sort sort);\n\n /**\n * Returns the number of instances that the given {@link Specification} will return.\n * \n * @param spec the {@link Specification} to count instances for\n * @return the number of instances\n */\n long count(Specification<T> spec);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n但我认为它将创造出弗兰肯斯坦生物:一半是 DAO,一半是存储库。
另一种解决方案是直接实现基本接口和标记接口:org.springframework.data.repository.Repository以及JpaSpecificationExecutor类似的接口:
public interface CustomerRepository extends Repository<Customer, Long>, JpaSpecificationExecutor {\n \xe2\x80\xa6\n}\nRun Code Online (Sandbox Code Playgroud)\n\n通过这种方式,您可以拥有一个真正的存储库,仅包含规范方法。
\n不知道有没有效果。我从来没有尝试过。
编辑:回复评论
\n\n存储库模式是 Hibernate 不提供开箱即用的解决方案的概念。
\n但是 Hibernate 以及更普遍的 JPA 2 规范确实提供了 Criteria 作为将规范创建为类的基本成分。
\n然后,您可以创建一个自定义类,通过提出所需的方法并将规范作为输入来实现存储库模式。\n我认为你可以使用 ORM 和存储库,因为你可以通过使用标准 API 来使用具有规范的 ORM。\n有些人反对 ORM 和存储库,我不同意。ORM 不是基于 DAO 模式。DAO 是操作数据库中数据的方式。ORM 是构建数据对象以表示数据库结构的方法。\n例如,通过使用两者,您可以从规范的灵活性以及关系对象映射和实体之间编织的强大功能中受益。
\n如果您不使用 ORM 或像 IBatis 那样的 ORM,您应该自己编写 ORM 为您提供的内容:对象关系映射。
| 归档时间: |
|
| 查看次数: |
5037 次 |
| 最近记录: |