网站为何突然不收录了,网站做弹窗广告,中国风景摄影网,中国最厉害的公关人【Spring连载】使用Spring Data的Repositories----自定义存储库实现 一、定制单个存储库1.1 配置1.2 歧义的解决1.3 手动装配 二、自定义基础存储库 Spring Data提供了各种选项#xff0c;可以用很少的编码来创建查询方法。但是#xff0c;当这些选项不能满足你的需求时… 【Spring连载】使用Spring Data的Repositories----自定义存储库实现 一、定制单个存储库1.1 配置1.2 歧义的解决1.3 手动装配 二、自定义基础存储库 Spring Data提供了各种选项可以用很少的编码来创建查询方法。但是当这些选项不能满足你的需求时你还可以为存储库方法提供自己的自定义实现。本节将介绍如何做到这一点。 一、定制单个存储库
要用自定义功能丰富存储库你必须首先定义一个fragment接口和自定义功能的实现如下所示 自定义存储库功能的接口
interface CustomizedUserRepository {void someCustomMethod(User user);
}自定义存储库功能的实现
class CustomizedUserRepositoryImpl implements CustomizedUserRepository {public void someCustomMethod(User user) {// Your custom implementation}
}与fragment接口相对应的类名中最重要的部分是Impl后缀。 实现本身不依赖于Spring Data可以是一个常规的Spring bean。因此你可以使用标准的依赖注入行为来注入对其他bean如JdbcTemplate的引用参与aspects等等。 然后你可以让你的存储库接口扩展fragment接口如下所示 对存储库接口的更改
interface UserRepository extends CrudRepositoryUser, Long, CustomizedUserRepository {// Declare query methods here
}使用你的存储库接口扩展fragment接口将CRUD和自定义功能结合起来使其可用于客户端。 Spring Data存储库是通过使用组成存储库组合的fragments来实现的。Fragments是基础存储库、功能切面如QueryDsl和自定义接口及他们的实现。每次向存储库接口添加接口时都会通过添加fragment来增强组合。基本存储库和存储库切面的实现由每个Spring Data模块提供。 以下示例展示了自定义接口及其实现 Fragments及其实现
interface HumanRepository {void someHumanMethod(User user);
}class HumanRepositoryImpl implements HumanRepository {public void someHumanMethod(User user) {// Your custom implementation}
}interface ContactRepository {void someContactMethod(User user);User anotherContactMethod(User user);
}class ContactRepositoryImpl implements ContactRepository {public void someContactMethod(User user) {// Your custom implementation}public User anotherContactMethod(User user) {// Your custom implementation}
}下面的示例展示了扩展CrudRepository的自定义存储库的接口: 对存储库接口的更改
interface UserRepository extends CrudRepositoryUser, Long, HumanRepository, ContactRepository {// Declare query methods here
}存储库可以由多个自定义实现组成这些实现按照声明的顺序导入。自定义实现的优先级高于基本实现和存储库切面。这种排序使您可以覆盖基本存储库和切面方法并在两个fragments提供相同的方法签名时解决歧义。存储库fragments不限于在单个存储库接口中使用。多个存储库可能使用一个fragment接口允许你在不同的存储库中重用自定义。 以下示例展示了一个存储库fragment及其实现 Fragments覆盖save(…)
interface CustomizedSaveT {S extends T S save(S entity);
}class CustomizedSaveImplT implements CustomizedSaveT {public S extends T S save(S entity) {// Your custom implementation}
}下面的示例展示了使用上述存储库片段的存储库: 自定义存储库接口
interface UserRepository extends CrudRepositoryUser, Long, CustomizedSaveUser {
}interface PersonRepository extends CrudRepositoryPerson, Long, CustomizedSavePerson {
}1.1 配置
存储库基础结构试图通过扫描在其中找到存储库的包下面的类来自动检测自定义实现片段(fragments)。这些类需要遵循将后缀默认追加Impl的命名约定。 以下示例展示了一个使用默认后缀的存储库和一个为后缀设置自定义值的存储库 例1配置示例
repositories base-packagecom.acme.repository /repositories base-packagecom.acme.repository repository-impl-postfixMyPostfix /EnableMongoRepositories(repositoryImplementationPostfix MyPostfix)
class Configuration { … }前面示例中的第一个配置试图查找一个名为“com.acme.repository.CustomizedUserRepositoryImpl”的类以充当自定义存储库实现。第二个示例试图查找“com.acme.repository.CustomizedUserRepositoryMyPostfix”。
1.2 歧义的解决
如果在不同的包中找到多个具有匹配类名的实现那么Spring Data将使用bean名称来确定要使用哪一个。 给定前面显示的CustomizedUserRepository的以下两个自定义实现将使用第一个实现。它的bean名称是customizedUserRepositoryImpl它与fragment接口CustomizedUserRepository加上后缀Impl的名称相匹配。 例2解决Resolution不明确的实现
package com.acme.impl.one;class CustomizedUserRepositoryImpl implements CustomizedUserRepository {// Your custom implementation
}Copied!
package com.acme.impl.two;Component(specialCustomImpl)
class CustomizedUserRepositoryImpl implements CustomizedUserRepository {// Your custom implementation
}如果你用Component(“specialCustom”)注解UserRepository接口那么bean名称加上Impl将与“com.acme.impl.two”中为存储库实现定义的名称相匹配并使用它来代替第一个。
1.3 手动装配
如果你的自定义实现仅使用基于注解的配置和自动装配那么前面展示的方法效果很好因为它被当成任何其他Spring bean。如果你的实现fragment bean需要特殊的装配那么你可以声明bean并根据上一节中描述的约定对其进行命名。然后基础结构infrastructure通过名称引用手动定义的bean定义而不是自己创建一个定义。以下示例展示了如何手动装配自定义实现 例3手动装配自定义实现
repositories base-packagecom.acme.repository /beans:bean iduserRepositoryImpl class…!-- further configuration --
/beans:beanclass MyClass {MyClass(Qualifier(userRepositoryImpl) UserRepository userRepository) {…}
}二、自定义基础存储库
当你想要自定义基本存储库行为以使所有存储库都受到影响时上一节中描述的方法需要自定义每个存储库接口。要更改所有存储库的行为可以创建一个扩展特定持久性技术存储库基类的实现。然后该类充当存储库代理的自定义基类如以下示例所示 自定义存储库基类
class MyRepositoryImplT, IDextends SimpleJpaRepositoryT, ID {private final EntityManager entityManager;MyRepositoryImpl(JpaEntityInformation entityInformation,EntityManager entityManager) {super(entityInformation, entityManager);// Keep the EntityManager around to used from the newly introduced methods.this.entityManager entityManager;}Transactionalpublic S extends T S save(S entity) {// implementation goes here}
}该类需要有一个父类的构造函数特定存储的存储库工厂实现使用该构造函数。如果存储库基类有多个构造函数请重写采用EntityInformation加上特定于存储库的基础结构对象如EntityManager或template类的构造函数。 最后一步是让Spring Data基础结构了解定制的存储库基类。在配置中你可以使用repositoryBaseClass来执行此操作如以下示例所示 例4配置自定义存储库基类
repositories base-packagecom.acme.repositorybase-class….MyRepositoryImpl /Configuration
EnableMongoRepositories(repositoryBaseClass MyRepositoryImpl.class)
class ApplicationConfiguration { … }