繁体   English   中英

如何传递 Map 或 List<object> 作为 JPA 查询的参数<div id="text_translate"><p>我需要将 map 作为 <Sting,String> 或 List 类型的输入参数传递到两个 JPA 列中,并将结果作为映射/列表中所有条目的记录列表。</p><p> 是这样的:</p><pre> @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);</pre><p> 或者</p><pre>@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);</pre><p> 但是应用程序不会运行,因为这不是有效的 jpa 查询。 我不想在循环中运行单个查询,而是寻找一个可以将结果作为列表给出的查询。</p></div></object>

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

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

是这样的:

@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 是一组键/值对,键为name ,值为relationName


    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();
    }

这个产生的查询应该有你想要的 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 实现。 或者你可以自己写。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM