您基本上有两种选择。第一个是提供每个存储库接口的实现。这可以在您的示例中看到。在这种情况下,您可以为一个实体存储库覆盖存储库的默认实现。这对于增强特殊实体存储库很有用,例如用于报告等。
另一个选项是当您想为所有存储库提供基本实现时,您需要使用基本存储库片段。当您只想为每个自定义存储库提供一个基本实现时,存储库片段可能非常有用。让我给你举个例子:
CustomReadRepository:
@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 应该在 Main 类中使用:
主类:
@EnableJpaRepositories(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)
public class App {
}
以及工厂的实现:
CustomRepositoryFactory:
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;
}
如果你想看一种真实的例子,请看问题here。