【问题标题】:Best practise when using Querydsl with Spring Data将 Querydsl 与 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

标签: spring spring-data spring-data-jpa querydsl


【解决方案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);
    }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 1970-01-01
      • 2022-06-22
      • 1970-01-01
      相关资源
      最近更新 更多