使用 Spring Data 和 Querydsl,我们可以只声明存储库接口(interface)并跳过实现类。一些具有特定名称或使用@Query 注解的方法,仅此而已。
但有时我想使用 JPAQuery 并自己定义方法的主体,比如说
@Repository
public class MyRepositoryImpl implements MyRepository {
@PersistenceContext
private EntityManager em;
@Override
public List<Tuple> someMethod(String arg) {
JPAQuery query = new JPAQuery(em);
...
}
但是这样我将不得不实现其他 MyRepository 接口(interface)方法,这会破坏 Spring Data 的所有优势!
我可以看到两个选项:
- 为每个存储库声明另一个接口(interface),然后正常实现它(接口(interface)数量翻倍)
- 将 EntityManager 注入(inject) @Service 类并在那里实现我的自定义方法
我更喜欢选项#2,但据我所知,在@Service 类中我们应该只调用存储库方法,所以它也不是一个完美的解决方案。
那么程序员是如何处理的呢?
最佳答案
您不应该实现实际的 Spring Data 存储库,而是必须声明另一个自定义接口(interface),您可以在其中放置自定义方法。
假设你有一个 MyRepository
,定义为
@Repository
public interface MyRepository extends JpaRepository<Tuple, Long> {}
现在您要添加您的自定义 findTuplesByMyArg()
,出于目的,您需要创建自定义存储库接口(interface)
public interface MyRepositoryCustom {
List<Tuple> findTuplesByMyArg(String myArg);
}
接下来是自定义接口(interface)的实现
public class MyRepositoryImpl implements MyRepositoryCustom {
@PersistenceContext
private EntityManager em;
@Override
public List<Tuple> findTuplesByMyArg(String myArg) {
JPAQuery query = new JPAQuery(em);
...
}
}
我们需要更改 MyRepository
声明,所以它扩展自定义存储库,以便
@Repository
public interface MyRepository extends JpaRepository<Tuple, Long>, MyRepositoryCustom {}
您可以通过注入(inject) MyRepository
轻松访问您的 findTuplesByMyArg()
,例如
@Service
public class MyService {
@Autowired
private MyRepository myRepository;
public List<Tuple> retrieveTuples(String myArg) {
return myRepository.findTuplesByMyArg(myArg);
}
}
注意名称在这里很重要(在 repo 实现中默认配置需要有 Impl
后缀)。
您可以找到所有需要的信息 here
关于spring - 将 Querydsl 与 Spring Data 一起使用时的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32088931/