为什么我需要一个独立的存储库片段接口?

46scxncf  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(338)

引用https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-实施
要使用自定义功能丰富存储库,必须首先为自定义功能定义片段接口和实现
示例32显示,对于不扩展的存储库,情况也是如此 CrudRepository (如示例31)或合并多个存储库接口(如示例33)。
它还指出
与片段接口相对应的类名中最重要的部分是impl后缀
但却不解释原因。
自定义存储库/存储库片段是如何工作的,为什么 @Repository 普通bean上的注解就足够了吗?

baubqpgj

baubqpgj1#

你基本上有两个选择。第一个是提供每个存储库接口的实现。这可以从你的例子中看出。在这种情况下,您可以为一个实体回购覆盖存储库的默认实现。这有助于增强特殊实体存储库,例如用于报告等。
另一种选择是,当您希望为所有存储库提供基本实现时,您需要使用基本存储库片段。当您只想为每个自定义存储库提供一个基本实现时,存储库片段非常有用。我举个例子:
自定义ReadRepository:

  1. @NoRepositoryBean
  2. public interface CustomReadRepository<T> extends Repository<T, String> {
  3. public List<T> someMethod();
  4. public List<T> someHighPerformanceMethod();
  5. }

现在假设我们需要一个接口,它将不同的存储库组合起来并调用它 DataRepository .
数据存储库:

  1. @NoRepositoryBean
  2. public interface DataRepository<T>
  3. extends CrudRepository<T, String>, CustomReadRepository<T> {
  4. }

下面的接口现在是扩展整个存储库的实体的特定存储库

  1. @Repository
  2. public interface UserRepository extends DataRepository<UserEntity> {
  3. }

  1. @Repository
  2. public interface OrderRepository extends DataRepository<OrderEntity> {
  3. }

现在我们只想为所有特定的存储库(orderrepository、userrepository等)提供一个实现。

  1. public class CustomReadRepositoryImpl<T> implements CustomReadRepository<T> {
  2. private static final EntityPathResolver resolver = SimpleEntityPathResolver.INSTANCE;
  3. private final JpaEntityInformation<T, ?> entityInformation;
  4. private final EntityManager entityManager;
  5. private final Querydsl entityManager;
  6. public CustomReadRepositoryImpl(JpaEntityInformation<T, ?> entityInformation,
  7. EntityManager entityManager) {
  8. this.entityManager = entityManager;
  9. this.entityInformation = entityInformation;
  10. }
  11. @Override
  12. public List<T> someMethod() {
  13. //do something and return result
  14. }
  15. @Override
  16. public List<T> someHighPerformanceMethod() {
  17. // do some high performance querying here
  18. }
  19. }

因此,您在这里基本上可以做的是增强您的存储库,并且只提供一个有用的实现,例如覆盖spring的默认实现(以便使其更快或出于任何原因)。您还可以提供新的定制回购和实现。
要在spring中访问片段实现,必须执行以下操作:
customrepositoryfactorybean:

  1. public class CustomRepositoryFactoryBean<T extends Repository<S, I>, S, I>
  2. extends JpaRepositoryFactoryBean<T, S, I> {
  3. public CustomRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
  4. super(repositoryInterface);
  5. }
  6. protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
  7. return new CustomRepositoryFactory(entityManager);
  8. }

这个bean应该在主类中使用:
主要类别:

  1. @EnableJpaRepositories(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)
  2. public class App {
  3. }

以及工厂的实施:
客户仓库工厂:

  1. public class CustomRepositoryFactory extends JpaRepositoryFactory {
  2. private final EntityManager entityManager;
  3. public CustomRepositoryFactory(EntityManager entityManager) {
  4. super(entityManager);
  5. this.entityManager = entityManager;
  6. }
  7. @Override
  8. protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata) {
  9. RepositoryFragments fragments = super.getRepositoryFragments(metadata);
  10. if (CustomReadRepository.class.isAssignableFrom(
  11. metadata.getRepositoryInterface())) {
  12. JpaEntityInformation<?, Serializable> entityInformation =
  13. getEntityInformation(metadata.getDomainType());
  14. Object customRepoFragment = getTargetRepositoryViaReflection(
  15. CustomReadRepositoryImpl.class, entityInformation, entityManager);
  16. fragments = fragments.append(RepositoryFragment.implemented(customRepoFragment));
  17. }
  18. return fragments;
  19. }

如果你想看一个真实的例子,看看这个问题。

展开查看全部

相关问题