UNION到JPA查询

时间:2013-09-23 11:55:37

标签: java jpa criteria

是否可以在JPA甚至“Criteria Builder”中查询“UNION”?

我正在寻找例子,但到目前为止我没有结果。

有没有人有任何使用它的例子?

或者那是原生sql吗?

8 个答案:

答案 0 :(得分:23)

SQL支持UNION,但JPA 2.0 JPQL不支持。大多数联合可以在连接方面完成,但有些不能,有些则更难以使用连接来表达。

EclipseLink支持UNION。

答案 1 :(得分:21)

根据具体情况,可以使用子查询,例如:

select e
from Entity e
where e.id in
(
  select e.id
  from Entity2 e2
       join e2.entity e
  where e2.someProperty = 'value'
)
      or e.id in
(
  select e.id
  from Entity3 e3
       join e3.entity e
  where e3.someProperty = 'value2'
)

答案 2 :(得分:5)

我想到了一件事(寻找完全相同的问题):

对同一实体映射执行两个不同的JPA查询,只需将第二个结果的对象添加到第一个结果的列表中(或设置为避免重复)。

这样你获得与UNION相同的效果,不同之处在于你使用两个SQL语句而不是一个。但实际上,我希望它的表现与发布一个UNION声明一样好。

答案 3 :(得分:2)

编写本机查询(将其设置为true,默认将其设置为false)-例如。

String findQuery = "select xyz from abc union select abc from def"
@Query(value = findQuery, nativeQuery = true)
//method

答案 4 :(得分:0)

  

SQL支持UNION,但JPA 2.0 JPQL不支持。 [Masudul]

解决此问题的一种方法是通过执行多个查询并将每个查询添加到结果集中这可能会更慢,但这是一个简单的解决方案:

Query query = em.createQuery("SELECT p FROM Person p  WHERE title = theTitle", Person.class);
Query query2 = em.createQuery("SELECT p FROM Person p  WHERE firstName = theFirstName", Person.class);
List<Person> list = query.getResultList();
List<Person> list2 = query2.getResultList();
LinkedHashSet<Person> result = new LinkedHashSet<Person>();
result.addAll(list);
result.addAll(list2);
//fun with result

答案 5 :(得分:0)

JPA没有直接的联合,我要做的是建立两个规范。

Specification<Task> specification = Specification.where(null);
Specification<Task> specification2 = Specification.where(null;

它们属于单个表,但是返回不同的值

specification = specification.and((root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.equal(criteriaBuilder.function(MONTH, Integer.class, root.get("deliveryExpirationDate")), month));
        specification2 = specification2.and((root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.lessThan(criteriaBuilder.function(MONTH, Integer.class, root.get("deliveryExpirationDate")), month))
            .and((root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.equal(root.get("enable"), true));

在此示例中,它是一个任务表,在第一个规范中,我需要启用和禁用当月的任务,在第二个规范中,我只需要启用前几个月的任务。

Specification<Task> specificationFullJoin = Specification.where(specification).or(specification2);

Esto es muyútilpara que la lista de tareas devueltas tengapaginación。

taskRepository.findAll(specificationFullJoin, pageable).map(TaskResponse::new); //Here you can continue adding filters, sort or search.

这对我有很大帮助,我希望这是他们正在寻找的东西,或者为他们服务的东西。

答案 6 :(得分:-2)

您可以在查询中直接使用UNION。 以下查询返回FRIENDSHIP表中的朋友ID。

例如:

TypedQuery<String> queryFriend = em.createQuery("SELECT f.Id FROM Friendship f WHERE f.frStuId = :stuId UNION "
                                 + "SELECT f.frStuId FROM Friendship f WHERE f.FriendId = :stuId", String.class);
queryFriend.setParameter("stuId", stuId);

List<String> futureFriends = queryFriend.getResultList();

答案 7 :(得分:-2)

使用EntityManager.createNativeQuery(...); 允许您使用UNION