代码之家  ›  专栏  ›  技术社区  ›  Amy B

使用Hibernate执行“IN”查询

  •  32
  • Amy B  · 技术社区  · 14 年前

    我有一个字符串中的id列表,并希望使用Hibernate获取具有这些id的行。 TrackedItem

    我的代码是:

    String idsText = "380, 382, 386";
    ArrayList<Long> ids = new ArrayList<Long>();
    
    for (String i : idsText.split(","))
    {
        ids.add(Long.getLong(i));
    }
    
    List<TrackedItem> items = TrackedItem.find("id IN (?)", ids).fetch();
    

    但这失败了: JPAQueryException occured : Error while executing query from models.TrackedItem where id IN (?): java.util.ArrayList cannot be cast to java.lang.Long

    IN 兼职?谢谢。

    3 回复  |  直到 14 年前
        1
  •  71
  •   themenace    6 年前

    JPQL查询的语法不正确。使用(带位置参数):

    List<Long> ids = Arrays.asList(380L, 382L, 386L);
    Query query = em.createQuery("FROM TrackedItem item WHERE item.id IN (?1)");
    query.setParameterList(1, ids)
    List<TrackedItem> items = query.getResultList();
    

    List<Long> ids = Arrays.asList(380L, 382L, 386L);
    Query query = em.createQuery("FROM TrackedItem item WHERE item.id IN :ids");
    query.setParameterList("ids", ids)
    List<TrackedItem> items = query.getResultList();
    

    以下是JPA 1.0规范中有关参数的相关章节:

    4.6.4.1位置参数

    • 输入参数由问号(?)前缀后跟整数指定。例如: ?1 .
    • 输入参数从1开始编号。

    命名参数是以“:”符号为前缀的标识符。它遵循第4.4.1节中定义的标识符规则。命名参数区分大小写。

    例子:

    SELECT c
    FROM Customer c
    WHERE c.status = :stat
    

    第3.6.1节描述了用于绑定命名查询参数的API

        2
  •  11
  •   depsypher    9 年前

    Query query = session.createQuery("FROM TrackedItem item WHERE item.id IN (:items)");
    query.setParameterList("items", Arrays.asList(380L, 382L, 386L));
    
    @SuppressWarnings("unchecked")
    List<TrackedItem> results = query.list();
    
        3
  •  1
  •   Aleksandar Radulović    5 年前

    即使查询执行正确,如果查询参数包含太多值,也可能会遇到错误。

    如果您使用的是Hibernate5.1或更高版本,解决这个问题的一个可能方法是使用Session.byMultipleIds()。

    session
        .byMultipleIds(TrackedItem.class)
        .multiLoad(1L, 2L, 3L);
    

    有关详细信息,请参阅 https://thoughts-on-java.org/fetch-multiple-entities-id-hibernate/