我想创建一个具有自定义行为的Spring Data JPA存储库,并使用Specification实现该自定义行为。我已经通过Spring Data JPA documentation for implementing custom behavior in a single repository来设置它,除了没有在自定义存储库中使用Spring Data Specification的示例。如果可能的话,怎么会这样做?
我没有看到在自定义实现中注入某些内容的方法。我认为我会很棘手并将存储库的CRUD存储库部分注入自定义部分,但这会导致循环实例化依赖。
我没有使用QueryDSL。谢谢。
答案 0 :(得分:5)
我想灵感的主要来源可能是SimpleJpaRepository
如何处理规范。要看的关键点是:
SimpleJpaRepository.getQuery(…)
- 它基本上创建了CriteriaQuery
并使用JPA Root
引导选择。后者是否适用于您的用例已经取决于您。我认为前者肯定适用。SimpleJpaRepository.applySpecificationToCriteria(…)
- 它基本上使用getQuery(…)
中生成的工件(即Root
和CriteriaQuery
)并将给定的Specification
应用于这些工件答案 1 :(得分:2)
这不是使用规范,所以不确定它是否与您相关,但我能够注入自定义行为的一种方式如下,
基本结构:如下
我。为通用父实体之后建模的实体类集创建通用接口。注意,这是可选的。在我的情况下,我需要这种层次结构,但它没有必要
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
}
II。将特定存储库从泛型(步骤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
}
III。在服务实现类
中使用上述存储库现在,Service类可能如下所示,
public interface GenericService<T extends GenericEntity, ID extends Serializable> {
// add specific methods you want to extend to user
}
通用实现类可以如下,
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
}
具体的实现类可以是
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;
}
}