是否可以在JPA甚至“Criteria Builder”中查询“UNION”?
我正在寻找例子,但到目前为止我没有结果。
有没有人有任何使用它的例子?
或者是原生sql?
SQL支持UNION,但JPA 2.0 JPQL不支持。大多数联合可以在连接方面完成,但有些不能,有些则更难以使用连接来表达。
EclipseLink支持UNION。
根据具体情况,可以使用子查询,例如:
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'
)
有一件事我想到了(寻找完全相同的问题):
对同一实体映射执行两个不同的JPA查询,只需将第二个结果的对象添加到第一个结果的列表(或设置为避免重复)。
这样你获得与UNION相同的效果,不同之处在于你使用两个SQL语句而不是一个。但实际上,我希望它的表现与发布一个UNION语句一样好。
写本机查询(设置为true,默认为false) - ex。
String findQuery = "select xyz from abc union select abc from def"
@Query(value = findQuery, nativeQuery = true)
//method
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);
这对于具有分页的返回任务列表非常有用。
taskRepository.findAll(specificationFullJoin, pageable).map(TaskResponse::new); //Here you can continue adding filters, sort or search.
它帮助了我很多,我希望它是他们正在寻找的东西,或者它为他们服务的东西。
使用EntityManager.createNativeQuery(...);它允许你使用UNION
您可以在查询中直接使用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();