如何将 Map 或 List<Object> 作为参数传递给 JPA 查询

how to pass Map or List<Object> as a parameter to JPA query

我需要将映射作为类型为 或 List 的输入参数传递到两个 JPA 列中,并将结果作为 map/list 中所有条目的记录列表。

像这样:

@Query(
      value =
          "SELECT e from #{#entityName} e where e.name = KEY(someMap) and e.relationName = VALUE(someMap)")
  List<Member> findByNameAndRelationNameIn(
          @Param("someMap") Map<String, String> someMap);

@Query(
      value =
          "SELECT e from #{#entityName} e where e.name IN (:#{#dataSpaceMembers.?[name]}) and e.dataSpaceName IN (:#{#dataSpaceMembers.?[dataSpaceName]})")
  List<DataSpaceMember> findByNameAndDataSpaceIn(
      @Param("dataSpaceMembers") List<DataSpaceMember> dataSpaceMembers);

但是应用程序没有 运行 因为这不是有效的 jpa 查询。 我不想 运行 循环中的单个查询,而是寻找一个可以将结果作为列表给出的查询。

我认为使用 @Query 符号不可能做到这一点,但是,就像 Chris 在评论中所说的那样,您可以非常快速地编写一些代码来使用条件查询动态创建这种语句。

我认为您正在寻找的代码应该是这样的,其中提供的 Map 是一组 key/value 对,键为 name,值为 [=13] =].


    EntityManager em;

    public List<Member> get(Map<String, String> map) {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Member> cq = cb.createQuery(Member.class);

        Root<Member> root = cq.from(Member.class);
        List<Predicate> predicates = new ArrayList<>();
        for (Map.Entry<String, String> e : map.entrySet()) {
            Predicate a = cb.equal(root.get("name"), e.getKey());
            Predicate b = cb.equal(root.get("relationName"), e.getValue());
            predicates.add(cb.and(a, b));
        }

        cq.where(cb.or(predicates.toArray(new Predicate[0])));
        return em.createQuery(cq).getResultList();
    }

生成的 Thr 查询应该包含您想要的 AND 和 OR 语句的组合,即

SELECT * FROM member WHERE ((name = ? AND relationName = ?) OR (name = ? AND relationName = ?) ... etc)

注:

由于 Map 只能包含一次密钥,您可以考虑使用 List<KeyValue<String, String>>List<Pair<String, String>>。 KeyValue 和 Pair 都可以在 Apache 公共库中找到,我相信 Spring 也包括一个 Pair 实现。或者您可以自己编写。