首页 文章

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

提问于
浏览
7

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

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

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

自定义行为界面:

@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:

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

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

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

1 回答

  • 12

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

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

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

    这个回购的实现:

    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();
    }
    

    实施定制汽车相关方法

    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工厂,就像在文档中一样

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

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

    <jpa:repositories base-package="com.example" factory-class="com.example.CustomRepositoryFactoryBean"/>
    

相关问题