Spring Jpa将自定义功能添加到所有存储库,同时将其他自定义功能添加到单个存储库

lin*_*tto 7 spring jpa spring-data spring-data-jpa

这里的Spring文档http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementations提供了向所有存储库或者a添加自定义功能的示例单个存储库,而不是两者.

假设我想向所有存储库添加一些自定义函数(使用自定义存储库工厂Bean),而另一些只添加到单个存储库(文档说使用自定义接口和自定义Impl); 我该怎么做到这一点?

一些示例代码,我将"setCurrentTenansInSession"方法添加到所有存储库; 现在我想将一个自定义方法(例如"newCustomMethod")添加到单个存储库(这是一个MyJpaRepository,就像我的自定义存储库工厂一样).我该怎么做呢?

自定义行为界面:

@NoRepositoryBean
public interface MyJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID> { 
    public void setCurrentTenantInSession(Object object);       
}
Run Code Online (Sandbox Code Playgroud)

自定义行为实现:

public class MultiTenantSimpleJpaRepository<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements MyJpaRepository<T, ID> {
    public void setCurrentTenantInSession(Object object) {
        //custom impl
    }
}
Run Code Online (Sandbox Code Playgroud)

自定义存储库工厂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);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后是自定义存储库工厂:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

kka*_*nev 12

您只需要在您提到的doc页面上组合这些方法.让我们Car成为您想拥有自定义存储库的实体.

CommonCustomRepository 定义添加到所有仓库的方法:

@NoRepositoryBean
public interface CommonCustomRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
    String getCustomValue();
}
Run Code Online (Sandbox Code Playgroud)

这个回购的实现:

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";
    }

}
Run Code Online (Sandbox Code Playgroud)

自定义方法 CarRepository

@NoRepositoryBean
public interface CustomCarRepository {

    public String getCustomCarValue();
}
Run Code Online (Sandbox Code Playgroud)

实现与汽车相关的定制方法

public class CarRepositoryImpl implements CustomCarRepository {

    @PersistenceContext
    private EntityManager em;

    @Override
    public String getCustomCarValue() {
        return "CustomCarValue";
    }
}
Run Code Online (Sandbox Code Playgroud)

组合界面 CarRepository

public interface CarRepository extends CommonCustomRepository<Car, Long>, CustomCarRepository {
}
Run Code Online (Sandbox Code Playgroud)

自定义repo工厂,就像在文档中一样

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

配置的最后一点,就像在文档中一样

<jpa:repositories base-package="com.example" factory-class="com.example.CustomRepositoryFactoryBean"/>
Run Code Online (Sandbox Code Playgroud)

  • 如`弹簧数据commons` 1.11指定`基类="com.example.CommonCustomRepositoryImpl"`而不是为`JPA弃用`工厂class`属性的:repositories`.指定基类时不需要工厂. (2认同)