2

可以将单个命名参数设置为 JPA 条件查询,如下所示。Long在这种情况下,参数是类型。

public StateTable find(Long id)
{
    CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
    CriteriaQuery<StateTable> criteriaQuery = criteriaBuilder.createQuery(StateTable.class);
    Metamodel metamodel=entityManager.getMetamodel();
    EntityType<StateTable> entityType = metamodel.entity(StateTable.class);
    Root<StateTable> root = criteriaQuery.from(entityType);

    ParameterExpression<Long> parameterExpression=criteriaBuilder.parameter(Long.class);
    criteriaQuery.where(criteriaBuilder.equal(root.get(StateTable_.stateId), parameterExpression));

    TypedQuery<StateTable> typedQuery = entityManager.createQuery(criteriaQuery);
    return typedQuery.setParameter(parameterExpression, id).getSingleResult();
}

StateTable方法内的这个查询返回我正在处理的(只是说状态)实体的单个对象,并对应于以下 JPQL 查询。

entityManager.createQuery("select s from StateTable s where s.stateId=:id")
             .setParameter("id", id)
             .getSingleResult();

我需要找到与通过提供的 id 列表相对应的不止一行java.util.List<Long>。以下是条件查询的不完整版本。

public List<StateTable> find(List<Long> ids)
{
    CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
    CriteriaQuery<StateTable> criteriaQuery=criteriaBuilder.createQuery(StateTable.class);
    Metamodel metamodel=entityManager.getMetamodel();
    EntityType<StateTable> entityType = metamodel.entity(StateTable.class);
    Root<StateTable> root = criteriaQuery.from(entityType);

    ParameterExpression<Long> parameterExpression = criteriaBuilder.parameter(Long.class);
    criteriaQuery.where(criteriaBuilder.in(root.get(StateTable_.stateId)).value(parameterExpression));

    TypedQuery<StateTable> typedQuery = entityManager.createQuery(criteriaQuery);
    return typedQuery.setParameter(parameterExpression, 1L).getResultList();
}

它使用了一个in()查询,但我让它只返回一行,因为我不知道是否可以设置一个 id 列表ParameterExpression

简而言之,这个条件查询应该对应于下面的 JPQL 查询。

entityManager.createQuery("from StateTable where stateId in(:id)")
             .setParameter("id", ids)
             .getResultList();

有没有办法将 a 设置List<Long>ParameterExpression指定的?

4

2 回答 2

3

以下方法对我有用。

public List<StateTable> find(List<Long> ids)
{
    CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
    CriteriaQuery<StateTable> criteriaQuery=criteriaBuilder.createQuery(StateTable.class);
    Metamodel metamodel=entityManager.getMetamodel();
    EntityType<StateTable> entityType = metamodel.entity(StateTable.class);
    Root<StateTable> root = criteriaQuery.from(entityType);

    //ParameterExpression<Long> parameterExpression = criteriaBuilder.parameter(Long.class);
    //criteriaQuery.where(criteriaBuilder.in(root.get(StateTable_.stateId)).value(parameterExpression));
    criteriaQuery.where(root.get(StateTable_.stateId).in(ids));

    TypedQuery<StateTable> typedQuery = entityManager.createQuery(criteriaQuery);
    return typedQuery.getResultList();
}

我刚刚添加了以下行。

criteriaQuery.where(root.get(StateTable_.stateId).in(ids));

从问题中查询的不完整版本中删除上述注释行。

于 2013-06-14T06:14:52.953 回答
3

我最近正在调查同样的事情,并找到了一个不应该影响服务器端查询缓存的解决方案。 使用 ParameterExpression 作为 In 子句的一部分

请注意,这应该是对 Jannik Jochem 在此页面答案下的评论的回应;但是,我的代表很少,所以如果你有足够的代表,请随意删除这篇文章并添加评论。

于 2015-07-01T11:55:09.053 回答