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

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

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

baubqpgj

baubqpgj1#

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

@NoRepositoryBean
public interface CustomReadRepository<T> extends Repository<T, String> {

  public List<T> someMethod();

  public List<T> someHighPerformanceMethod();
}

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

@NoRepositoryBean
public interface DataRepository<T>
  extends CrudRepository<T, String>, CustomReadRepository<T> {
}

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

@Repository
public interface UserRepository extends DataRepository<UserEntity> {

}

@Repository
public interface OrderRepository extends DataRepository<OrderEntity> {

}

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

public class CustomReadRepositoryImpl<T> implements CustomReadRepository<T> {

  private static final EntityPathResolver resolver = SimpleEntityPathResolver.INSTANCE;

  private final JpaEntityInformation<T, ?> entityInformation;
  private final EntityManager entityManager;
  private final Querydsl entityManager;

  public CustomReadRepositoryImpl(JpaEntityInformation<T, ?> entityInformation,
      EntityManager entityManager) {
    this.entityManager = entityManager;
    this.entityInformation = entityInformation;
  }

  @Override
  public List<T> someMethod() {
    //do something and return result
  }

  @Override
  public List<T> someHighPerformanceMethod() {
    // do some high performance querying here
  }
}

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

public class CustomRepositoryFactoryBean<T extends Repository<S, I>, S, I>
    extends JpaRepositoryFactoryBean<T, S, I> {

  public CustomRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
    super(repositoryInterface);
  }

  protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
    return new CustomRepositoryFactory(entityManager);
  }

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

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

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

public class CustomRepositoryFactory extends JpaRepositoryFactory {

  private final EntityManager entityManager;

  public CustomRepositoryFactory(EntityManager entityManager) {
    super(entityManager);
    this.entityManager = entityManager;
  }

  @Override
  protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata) {
    RepositoryFragments fragments = super.getRepositoryFragments(metadata);

    if (CustomReadRepository.class.isAssignableFrom(
        metadata.getRepositoryInterface())) {

      JpaEntityInformation<?, Serializable> entityInformation = 
          getEntityInformation(metadata.getDomainType());

      Object customRepoFragment = getTargetRepositoryViaReflection(
          CustomReadRepositoryImpl.class, entityInformation, entityManager);

      fragments = fragments.append(RepositoryFragment.implemented(customRepoFragment));
    }

    return fragments;
  }

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

相关问题