为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

临摹微笑 2023-06-21 15:52:19
我正在尝试使用 @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() 中,因为它位于存储库接口中。
查看完整描述

4 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

您可以使用规范来实现这一目标。规范类类似于(假设 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]));

    }

}

存储库需要扩展JpaSpecificationExecutor

public interface LocationRepository 
  extends JpaRepository<Location, Long>, JpaSpecificationExecutor<Location> {}

你会这样称呼它:

List<Location> results = repository.findAll(new LocationSpecification(listA, listB));

PS 上面写的是我的头顶,可能需要一些修改。


查看完整回答
反对 回复 2023-06-21
?
忽然笑

TA贡献1806条经验 获得超5个赞

使用JPA Specification API 


查看完整回答
反对 回复 2023-06-21
?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

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


查看完整回答
反对 回复 2023-06-21
?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

Criteria API / Specifications / Querydsl之间有一个很好的概述/比较。另一个库是Jooq,它有免费版本。

解决问题的方法是使用其中之一。

我更喜欢 Querydsl 因为

  • 它是类型安全的

  • 它与 Spring Data 配合良好

  • 您可以使用 IDE 中的代码完成功能

您还应该考虑到(目前)Querydsl 维护得不好。


查看完整回答
反对 回复 2023-06-21
  • 4 回答
  • 0 关注
  • 124 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信