将 Querydsl 与 Spring Data 一起使用时的最佳实践
Posted
技术标签:
【中文标题】将 Querydsl 与 Spring Data 一起使用时的最佳实践【英文标题】:Best practise when using Querydsl with Spring Data 【发布时间】:2015-11-12 08:45:56 【问题描述】:使用 Spring Data nad Querydsl 我们可以只声明存储库接口并跳过实现类。一些具有特定名称或使用@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 接口方法,这会破坏 Spring Data 的所有优势!
我可以看到两个选项:
为每个存储库声明另一个接口,然后正常实现它(接口数量翻倍) 将 EntityManager 注入 @Service 类并在那里实现我的自定义方法我更喜欢选项#2,但据我所知,在@Service 类中我们应该只调用存储库方法,所以它也不是一个完美的解决方案。
那么程序员是如何处理的呢?
【问题讨论】:
我也面临同样的问题,目前我选择了服务层来使用JPQLQuery
【参考方案1】:
您不应该实现实际的 Spring Data 存储库,而是必须声明另一个自定义接口,您可以在其中放置自定义方法。
假设你有一个MyRepository
,定义为
@Repository
public interface MyRepository extends JpaRepository<Tuple, Long>
现在您要添加您的自定义findTuplesByMyArg()
,出于某种目的,您需要创建自定义存储库接口
public interface MyRepositoryCustom
List<Tuple> findTuplesByMyArg(String myArg);
接下来是自定义接口的实现
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
您可以通过注入MyRepository
轻松访问您的findTuplesByMyArg()
,例如
@Service
public class MyService
@Autowired
private MyRepository myRepository;
public List<Tuple> retrieveTuples(String myArg)
return myRepository.findTuplesByMyArg(myArg);
注意名称在这里很重要(在 repo 实现中默认配置需要有 Impl
后缀)。
您可以找到所有需要的信息here
【讨论】:
【参考方案2】:我建议对上面的答案进行小幅纠正,尝试使用 JPAQueryFactory。最好利用提供的工厂类。
public class MyRepositoryImpl implements MyRepositoryCustom
@Autowired
private JPAQueryFactory factory;
@Override
public List<Tuple> findTuplesByMyArg(String myArg)
JPAQuery query = factory.query();
...
@Configuration
public class Config
@Autowired
private EntityManager em;
@Bean
public JPAQueryFactory jpaQueryFactory()
return new JPAQueryFactory(em);
【讨论】:
以上是关于将 Querydsl 与 Spring Data 一起使用时的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章
使用 QueryDSL 使用 Spring Data MongoDB 查询 DBRef
NoSuchMethodException QueryDSL 与 Spring Boot 和 Spring Data Mongo
Spring Data REST 的 QueryDSL 集成可以用来执行更复杂的查询吗?
Spring Data JPA - 规范和 Querydsl