如何将 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 实现。或者您可以自己编写。
我需要将映射作为类型为
像这样:
@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 实现。或者您可以自己编写。