将 Querydsl 与 Spring Data 结合使用时的最佳实践

问题描述 投票:0回答:2

使用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类中我们应该只调用存储库方法,所以它也不是一个完美的解决方案。

那么程序员如何处理呢?

spring spring-data spring-data-jpa querydsl
2个回答
22
投票

您不应该实现实际的 Spring Data 存储库,而是必须声明另一个自定义接口,您可以在其中放置自定义方法。

假设您有一个

MyRepository
,定义为

@Repository
public interface MyRepository extends JpaRepository<Tuple, Long> {}

现在您想要添加自定义

findTuplesByMyArg()
,出于目的,您需要创建自定义存储库界面

public interface MyRepositoryCustom {
   List<Tuple> findTuplesByMyArg(String myArg);
}

接下来是自定义接口的实现

public class MyRepositoryCustomImpl 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 {}

您可以通过注入

findTuplesByMyArg()
轻松访问您的
MyRepository
,例如

@Service
public class MyService {
   @Autowired
   private MyRepository myRepository;

   public List<Tuple> retrieveTuples(String myArg) { 
      return myRepository.findTuplesByMyArg(myArg);
   }
}

请注意,名称在这里很重要(在仓库实现中默认配置需要有

Impl
后缀)。

您可以在这里找到所有需要的信息


10
投票

我建议对上面的答案进行一些小修正,它尝试使用 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);
}

}
© www.soinside.com 2019 - 2024. All rights reserved.