将 IN 子句列表添加到 JPA 查询

Posted

技术标签:

【中文标题】将 IN 子句列表添加到 JPA 查询【英文标题】:Adding IN clause List to a JPA Query 【发布时间】:2011-05-21 16:46:50 【问题描述】:

我构建了一个 NamedQuery,如下所示:

@NamedQuery(name = "EventLog.viewDatesInclude",
        query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND "
        + "el.timeMark <= :dateTo AND "
        + "el.name IN (:inclList)")

我想要做的是用一个项目列表而不是一个项目来填写参数 :inclList 。例如,如果我有一个 new List&lt;String&gt;() "a", "b", "c" 我如何在 :inclList 参数中得到它?它只让我编码一个字符串。例如:

setParameter("inclList", "a") // works

setParameter("inclList", "a, b") // does not work

setParameter("inclList", "'a', 'b'") // does not work

setParameter("inclList", list) // throws an exception

我知道我可以只构建一个字符串并从中构建整个查询,但我想避免开销。有更好的方法吗?

相关问题:如果列表非常大,有什么好的方法来构建这样的查询吗?

【问题讨论】:

这是***.com/questions/1557085/… 的副本,但此线程提供了有用的答案。 【参考方案1】:

您必须转换为List,如下所示:

    String[] valores = hierarquia.split(".");       
    List<String> lista =  Arrays.asList(valores);

    String jpqlQuery = "SELECT a " +
            "FROM AcessoScr a " +
            "WHERE a.scr IN :param ";

    Query query = getEntityManager().createQuery(jpqlQuery, AcessoScr.class);                   
    query.setParameter("param", lista);     
    List<AcessoScr> acessos = query.getResultList();

【讨论】:

谢谢这个答案对我有帮助 这是最佳答案。【参考方案2】:

正确的 JPA 查询格式是:

el.name IN :inclList

如果您使用旧版本的 Hibernate 作为您的提供程序,您必须编写:

el.name IN (:inclList)

但这是一个错误 (HHH-5126)(编辑:现在已解决)。

【讨论】:

感谢区分老版本Hibernate使用()【参考方案3】:
public List<DealInfo> getDealInfos(List<String> dealIds) 
        String queryStr = "SELECT NEW com.admin.entity.DealInfo(deal.url, deal.url, deal.url, deal.url, deal.price, deal.value) " + "FROM Deal AS deal where deal.id in :inclList";
        TypedQuery<DealInfo> query = em.createQuery(queryStr, DealInfo.class);
        query.setParameter("inclList", dealIds);
        return query.getResultList();
    

适用于我的 JPA 2、Jboss 7.0.2

【讨论】:

【参考方案4】:

当使用带有集合值参数的IN 时,您不需要(...)

@NamedQuery(name = "EventLog.viewDatesInclude", 
    query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND " 
    + "el.timeMark <= :dateTo AND " 
    + "el.name IN :inclList") 

【讨论】:

不...我的情况正好相反。如果我使用 :inclList 那么它不起作用。如果我使用 IN (:inclList) 那么它可以工作。 另请注意:参数的类型必须是对象的集合(而不是数组)。对象必须与字段的类型相匹配。 .toString() 不能替代 String 类 我认为这是随着 Hibernate 的版本而改变的,据我所知,在使用 IN 时,当变量周围没有括号时出现错误。奇怪的是,如果它不向后兼容.. 这确实是一个休眠错误(需要括号),已在 3.6.1 中修复 对于相关问题:如果列表非常大,执行中可能会受到限制。例如。甲骨文 11g。最大限度。 1000 个列表元素作为参数是可能的。一种解决方法是将列表切入 subLists 并收集结果。 JPA 本身不限制列表大小。

以上是关于将 IN 子句列表添加到 JPA 查询的主要内容,如果未能解决你的问题,请参考以下文章

JPA - 带有in子句和不区分大小写的规范

如何保持 Spring Data JPA 或 Hibernate 中“in”子句中提供的顺序 [重复]

JPA Criteria builder IN 子句查询

如何在 JPA 命名查询的 IN 子句中使用动态参数?

将值列表从 Python 传递到 SQL 查询的 IN 子句

具有 CSV 值的列上的 JPA 查询 IN 子句未返回确切结果