Подтвердить что ты не робот

Запрос UNION на JPA

Можно ли запросить "СОЮЗ" в JPA и даже "Criteria Builder"?

Я ищу примеры, но до сих пор я не получил никакого результата.

Есть ли у кого-нибудь примеры того, как его использовать?

Или это будет с native sql?

4b9b3361

Ответ 1

SQL поддерживает UNION, а JPA 2.0 JPQL - нет. Большинство союзов может быть сделано с точки зрения объединений, но некоторые не могут, а некоторые сложнее выразить с помощью объединений.

EclipseLink поддерживает UNION.

Ответ 2

В зависимости от случая, можно использовать вспомогательные запросы, например:

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'
)

Ответ 3

Одна вещь приходит мне на ум (для поиска той же самой проблемы):

Выполните два разных запроса JPA для одного и того же сопоставления объектов и просто добавьте объекты второго результата в список (или установите, чтобы избежать дублирования) первого результата.

Таким образом, вы получаете тот же эффект, что и с UNION, разница заключается в том, что вы используете два оператора SQL вместо одного. Но на самом деле я бы ожидал, что это будет так же хорошо, как выдать один оператор UNION.

Ответ 4

написать собственный запрос (установить его в true, по умолчанию его false) - напр.

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

Ответ 5

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

Ответ 6

Прямого объединения для 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 útil para que la lista de tareas devueltas tenga paginación.

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

Это мне очень помогает, надеюсь, это то, что они ищут или что-то им служит.

Ответ 7

Вы можете напрямую использовать UNION в своем запросе. Следующий запрос возвращает идентификатор друзей из таблицы FRIENDSHIP.

Например:

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();

Ответ 8

using EntityManager.createNativeQuery(...); Это позволяет вам использовать UNION