Spring Data JPA:使用规范实现自定义存储库行为
Spring Data JPA: Implementing Custom Repository Behavior with Specifications
我想创建一个具有自定义行为的 Spring Data JPA 存储库,并使用自定义存储库中的 Specifications. I have gone through the Spring Data JPA documentation for implementing custom behavior in a single repository to set this up, except there is no example of using a Spring Data Specification 实现该自定义行为。如果可能的话,如何做到这一点?
我没有看到一种方法可以将某些东西注入到采用规范的自定义实现中。我以为我会很狡猾,将存储库的 CRUD 存储库部分注入自定义部分,但这会导致循环实例化依赖。
我没有使用 QueryDSL。谢谢。
我想灵感的主要来源可能是 SimpleJpaRepository
如何处理规范。要看的关键点是:
SimpleJpaRepository.getQuery(…)
- 它基本上是创建一个 CriteriaQuery
并使用 JPA Root
引导一个 select。后者是否适用于您的用例已经取决于您。我想前者肯定适用。
SimpleJpaRepository.applySpecificationToCriteria(…)
- 它基本上使用 getQuery(…)
中产生的工件(即 Root
和 CriteriaQuery
)并将给定的 Specification
应用到这些文物。
这不是使用规范,所以不确定它是否与您相关,但我能够注入自定义行为的一种方法如下,
基本结构:如下
我。为实体集 classes 创建一个通用接口,这些实体是在通用父实体之后建模的。请注意,这是可选的。就我而言,我需要这种层次结构,但没有必要
public interface GenericRepository<T> {
// add any common methods to your entity hierarchy objects,
// so that you don't have to repeat them in each of the children entities
// since you will be extending from this interface
}
二。从通用(第 1 步)和 JPARepository 扩展特定存储库为
public interface MySpecificEntityRepository extends GenericRepository<MySpecificEntity>, JpaRepository<MySpecificEntity, Long> {
// add all methods based on column names, entity graphs or JPQL that you would like to
// have here in addition to what's offered by JpaRepository
}
三。在您的服务实现中使用上述存储库 class
现在,服务 class 可能看起来像这样,
public interface GenericService<T extends GenericEntity, ID extends Serializable> {
// add specific methods you want to extend to user
}
泛型实现class可以如下,
public abstract class GenericServiceImpl<T extends GenericEntity, J extends JpaRepository<T, Long> & GenericRepository<T>> implements GenericService<T, Long> {
// constructor takes in specific repository
public GenericServiceImpl(J genericRepository) {
// save this to local var
}
// using the above repository, specific methods are programmed
}
具体实现class即可
public class MySpecificEntityServiceImpl extends GenericServiceImpl<MySpecificEntity, MySpecificEntityRepository> implements MySpecificEntityService {
// the specific repository is autowired
@Autowired
public MySpecificEntityServiceImpl(MySpecificEntityRepository genericRepository) {
super(genericRepository);
this.genericRepository = (MySpecificEntityRepository) genericRepository;
}
}
我想创建一个具有自定义行为的 Spring Data JPA 存储库,并使用自定义存储库中的 Specifications. I have gone through the Spring Data JPA documentation for implementing custom behavior in a single repository to set this up, except there is no example of using a Spring Data Specification 实现该自定义行为。如果可能的话,如何做到这一点?
我没有看到一种方法可以将某些东西注入到采用规范的自定义实现中。我以为我会很狡猾,将存储库的 CRUD 存储库部分注入自定义部分,但这会导致循环实例化依赖。
我没有使用 QueryDSL。谢谢。
我想灵感的主要来源可能是 SimpleJpaRepository
如何处理规范。要看的关键点是:
SimpleJpaRepository.getQuery(…)
- 它基本上是创建一个CriteriaQuery
并使用 JPARoot
引导一个 select。后者是否适用于您的用例已经取决于您。我想前者肯定适用。SimpleJpaRepository.applySpecificationToCriteria(…)
- 它基本上使用getQuery(…)
中产生的工件(即Root
和CriteriaQuery
)并将给定的Specification
应用到这些文物。
这不是使用规范,所以不确定它是否与您相关,但我能够注入自定义行为的一种方法如下,
基本结构:如下
我。为实体集 classes 创建一个通用接口,这些实体是在通用父实体之后建模的。请注意,这是可选的。就我而言,我需要这种层次结构,但没有必要
public interface GenericRepository<T> { // add any common methods to your entity hierarchy objects, // so that you don't have to repeat them in each of the children entities // since you will be extending from this interface }
二。从通用(第 1 步)和 JPARepository 扩展特定存储库为
public interface MySpecificEntityRepository extends GenericRepository<MySpecificEntity>, JpaRepository<MySpecificEntity, Long> { // add all methods based on column names, entity graphs or JPQL that you would like to // have here in addition to what's offered by JpaRepository }
三。在您的服务实现中使用上述存储库 class
现在,服务 class 可能看起来像这样,
public interface GenericService<T extends GenericEntity, ID extends Serializable> { // add specific methods you want to extend to user }
泛型实现class可以如下,
public abstract class GenericServiceImpl<T extends GenericEntity, J extends JpaRepository<T, Long> & GenericRepository<T>> implements GenericService<T, Long> { // constructor takes in specific repository public GenericServiceImpl(J genericRepository) { // save this to local var } // using the above repository, specific methods are programmed }
具体实现class即可
public class MySpecificEntityServiceImpl extends GenericServiceImpl<MySpecificEntity, MySpecificEntityRepository> implements MySpecificEntityService { // the specific repository is autowired @Autowired public MySpecificEntityServiceImpl(MySpecificEntityRepository genericRepository) { super(genericRepository); this.genericRepository = (MySpecificEntityRepository) genericRepository; } }