JPA多选

时间:2012-02-08 10:30:33

标签: jpa criteria

我使用EclipseLink作为JPA提供程序。

我想通过在线一个条件查询来查询以获取与某些IDs对应的所有名称。

Root<UserAccount> root = criteria.from(UserAccount.class);
List<Selection<?>> select = new ArrayList<Selection<?>>();
    for (MyElement element : list) {
   Expression<String> firstName = root.get("firstName");
   Expression<String> lastName = root.get("lastName");
   Expression<Integer> id = root.get("id");
   select.add(criteria
                .multiselect(
                        firstName.alias(element.getId() + "_"
                                + element.getEntity() + "f"),
                        lastName.alias(element.getId() + "_"
                                + element.getEntity() + "l"))
                .where(criteriaBuilder.equal(id, element.getAuthorId()))
                .from(UserAccount.class)
                .alias(element.getId() + "_" + element.getEntity()));
}
criteria.multiselect(select);
TypedQuery<Tuple> q = em.createQuery(criteria);
for (Tuple t : q.getResultList()) {
        for (OverviewEntity element : list) {
 System.out.println("////"
                        + t.get(element.getId().toString() + "_"+element.getEntity()+"f",
                                String.class));

element.getId() + "_" + element.getEntity() + "f"我打算创建一个唯一的别名。

问题是我得到的只是null。为什么?我应该如何在一个查询中获得所有这些(这样它不会变得耗时)?

2 个答案:

答案 0 :(得分:8)

您的代码似乎非常混乱,而且过于复杂。

JPQL

Select u.firstName, u.lastName, u.id from UserAccount u where u.id in (:ids)

似乎有效,

在标准中,这是

Root<UserAccount> root = criteria.from(UserAccount.class);
criteria.multiselect(root.get("firstName"), root.get("lastName"), root.get("id"));
criteria.where(criteriaBuilder.in(root.get("id"), criteriaBuilder.parameter("ids"));

答案 1 :(得分:2)

正如评论中所建议的那样,我会寻求一个更简单的解决方案,比如

List<Integer> myList = ....;  // place here your ids
TypedQuery<UserAccount> q = em.createQuery("select u from UserAccount u where u.id in (:myList)", UserAccount.class);

或使用CriteriaBuilder和Metamodel的等效查询:

Root<UserAccount> root = q.from(UserAccount.class);
Expression<Integer> exp = root.get(UserAccount_.id);
Predicate predicate = exp.in(myList);
criteria.where(predicate);

返回的resultList包含附加到PersistenceContext的实体实例。这意味着您将能够毫不费力地获得Transient属性。

关于性能,仅在极端情况下可能存在显着差异,例如返回列表的大小非常大,或者您必须以高频率重复此查询时。但这需要深入分析。