Spring Jpa 将自定义功能添加到所有存储库,同时将其他自定义功能添加到单个存储库 [英] Spring Jpa adding custom functionality to all repositories and at the same time other custom funcs to a single repository
问题描述
Spring 文档在此 http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementations 给出了向所有添加自定义功能的示例存储库或单个存储库,而不是两者.
Spring documentation here http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementations gives example to add custom functionalities to all repositories or to a single repositories, not both.
假设我想将一些自定义函数添加到所有存储库(使用自定义存储库工厂 Bean),而其他一些仅添加到单个存储库(文档说要使用自定义接口和自定义 Impl);我怎样才能做到这一点?
Let suppose I want to add some custom funcs to all repositories (using Custom Repository Factory Bean) and some other only to a single repositories (docs says to use a Custom Interface and a Custom Impl); how can I achieve this?
一些示例代码,其中我向所有存储库添加了setCurrentTenansInSession"方法;现在我想添加一个自定义方法,例如newCustomMethod",到单个存储库(即 MyJpaRepository,对于我的自定义存储库工厂).我该怎么做?
Some example code where I added "setCurrentTenansInSession" method to all repositories; now I want to add a custom method, e.g. "newCustomMethod", to ona single repository (that is a MyJpaRepository, as for my custom repository factory). How do I do this?
自定义行为界面:
@NoRepositoryBean
public interface MyJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
public void setCurrentTenantInSession(Object object);
}
自定义行为实现:
public class MultiTenantSimpleJpaRepository<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements MyJpaRepository<T, ID> {
public void setCurrentTenantInSession(Object object) {
//custom impl
}
}
自定义仓库工厂 bean :
Custom repository factory bean :
public class MultiTenantJpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {
@Override
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new MultiTenantJpaRepositoryFactory(entityManager);
}
}
最后是自定义存储库工厂:
And finally the custom repository factory :
public class MultiTenantJpaRepositoryFactory extends JpaRepositoryFactory {
public MultiTenantJpaRepositoryFactory(EntityManager entityManager) {
super(entityManager);
}
@Override
protected JpaRepository<?, ?> getTargetRepository(RepositoryMetadata metadata, EntityManager entityManager) {
final JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
final SimpleJpaRepository<?, ?> repo = new MultiTenantSimpleJpaRepository(entityInformation, entityManager);
repo.setLockMetadataProvider(LockModeRepositoryPostProcessor.INSTANCE.getLockMetadataProvider());
return repo;
}
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
return MultiTenantSimpleJpaRepository.class;
}
}
推荐答案
您只需要结合您提到的文档页面上的方法.让 Car
成为您想要为其拥有自定义存储库的实体.
You just need to combine the approaches on the doc page you mentioned. Let Car
be the entity you want to have a custom repository for.
CommonCustomRepository
定义添加到所有 repos 的方法:
CommonCustomRepository
defines the methods added to all repos:
@NoRepositoryBean
public interface CommonCustomRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
String getCustomValue();
}
这个 repo 的实现:
The implementation for this repo:
public class CommonCustomRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CommonCustomRepository<T, ID> {
public CommonCustomRepositoryImpl(Class<T> domainClass, EntityManager em) {
super(domainClass, em);
}
public CommonCustomRepositoryImpl(JpaEntityInformation<T, ?> entityInformation,
EntityManager entityManager) {
super(entityInformation, entityManager);
}
@Override
public String getCustomValue() {
return "CustomValue";
}
}
CarRepository
@NoRepositoryBean
public interface CustomCarRepository {
public String getCustomCarValue();
}
自定义汽车相关方法的实现
Implementation of the custom car-related methods
public class CarRepositoryImpl implements CustomCarRepository {
@PersistenceContext
private EntityManager em;
@Override
public String getCustomCarValue() {
return "CustomCarValue";
}
}
CarRepository
public interface CarRepository extends CommonCustomRepository<Car, Long>, CustomCarRepository {
}
自定义 repo factory,就像在文档中一样
Custom repo factory, just like in the documentation
public class CustomRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends
JpaRepositoryFactoryBean<R, T, I> {
@Override
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new CustomRepositoryFactory(entityManager);
}
private static class CustomRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
private EntityManager entityManager;
public CustomRepositoryFactory(EntityManager entityManager) {
super(entityManager);
this.entityManager = entityManager;
}
@Override
protected Object getTargetRepository(RepositoryMetadata metadata) {
return new CommonCustomRepositoryImpl<T, I>((Class<T>) metadata.getDomainType(), entityManager);
}
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
// The RepositoryMetadata can be safely ignored, it is used by the JpaRepositoryFactory
// to check for QueryDslJpaRepository's which is out of scope.
return CommonCustomRepositoryImpl.class;
}
}
}
最后一点配置,就像在文档中一样
The final bit of configuration, just like in the docs
<jpa:repositories base-package="com.example" factory-class="com.example.CustomRepositoryFactoryBean"/>
这篇关于Spring Jpa 将自定义功能添加到所有存储库,同时将其他自定义功能添加到单个存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!