如何根据函数的输出在@Query 中使用查询字符串

我正在尝试使用 @Query 注释进行查询并且它工作得很好,因为它总是只有一个条件,但现在我有多个条件并且我希望我的查询字符串根据参数动态更改。

假设我有 2 个字符串列表,listA 和 listB 我希望我的查询是

@Query("SELECT l FROM location AS l WHERE l.a IN :listA")

当listA不为空且listB为空时,并且

@Query("SELECT l FROM location AS l WHERE l.b IN :listB")

当 listB 不为空且 listB 为空时,并且

@Query("SELECT l FROM location AS l WHERE l.a IN :listA) AND l.b IN :listB"

当两个列表都不为空时。

我一直在尝试查看是否可以从其他函数获取查询字符串。

我可以根据列表生成字符串,但我只是不知道如何将输出字符串放入 @Query() 中,因为它位于存储库接口中。


临摹微笑
浏览 126回答 4
4回答

慕森王

您可以使用规范来实现这一目标。规范类类似于(假设 a、b 是文本列):public class LocationSpecification implements Specification<Location> {    public LocationSpecification(final List<String> listA, final List<String> listB) {        this.listA = listA;        this.listB = listB;    }    private final List<String> listA;    private final List<String> listB;    @Override    public Predicate toPredicate(Root<Location> root, CriteriaQuery<?> query, CriteriaBuilder cb) {        List<Predicate> predicates = new ArrayList<>();        if (listA != null) {            predicates.add(root.<String>get("a").in(listA));        }        if (listB != null) {            predicates.add(root.<String>get("b").in(listB));        }        return cb.and(predicates.toArray(new Predicate[0]));    }}存储库需要扩展JpaSpecificationExecutorpublic interface LocationRepository    extends JpaRepository<Location, Long>, JpaSpecificationExecutor<Location> {}你会这样称呼它:List<Location> results = repository.findAll(new LocationSpecification(listA, listB));PS 上面写的是我的头顶,可能需要一些修改。

忽然笑

使用JPA Specification API 

牧羊人nacy

您不必总是依赖@Query 来执行查询。更好的选择是创建存储过程并根据您的条件以编程方式调用它们。或者使用 Criteria 动态生成查询

收到一只叮咚

在Criteria API / Specifications / Querydsl之间有一个很好的概述/比较。另一个库是Jooq,它有免费版本。解决问题的方法是使用其中之一。我更喜欢 Querydsl 因为它是类型安全的它与 Spring Data 配合良好您可以使用 IDE 中的代码完成功能您还应该考虑到(目前)Querydsl 维护得不好。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java