web-dev-qa-db-ja.com

UNIONからJPAへのクエリ

JPAで「UNION」、さらには「Criteria Builder」を照会することは可能ですか?

私は例を探していますが、今のところ結果はありません。

使用方法の例はありますか?

それとも、ネイティブSQLですか?

18
Giovane

SQLはUNIONをサポートしていますが、JPA 2.0 JPQLはサポートしていません。ほとんどの結合は結合の観点から実行できますが、結合できないものもあり、結合を使用して表現するのがより困難なものもあります。

EclipseLinkはUNIONをサポートしています。

24
Masudul

場合によっては、次のようなサブクエリを使用できます。

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

一つのことが頭に浮かぶ(まったく同じ問題を探す):

同じエンティティマッピングに対して2つの異なるJPAクエリを実行し、最初の結果のリストに2番目の結果のオブジェクトを追加(または重複を避けるために設定)するだけです。

そうすれば、UNIONと同じ効果が得られますが、違いは1つではなく2つのSQLステートメントを使用することです。しかし実際には、1つのUNIONステートメントを発行するのと同じくらいのパフォーマンスを期待しています。

5
cslotty

ネイティブクエリの作成(trueに設定、デフォルトはfalse)-ex。

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

SQLはUNIONをサポートしていますが、JPA 2.0 JPQLはサポートしていません。 [マスダル]

これを解決する1つの方法は、複数のクエリを実行し、それぞれを結果セットに追加することです。これは遅くなりますが、簡単な解決策です。

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
0
Xanlantos

JPAには直接的な結合はありません。2つの仕様を作成することでした。

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

この例では、最初の仕様では現在の月のタスクを有効または無効にする必要があり、2番目の仕様では前の月の有効なタスクのみが必要なタスクのテーブルです。

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.

それが私を大いに助けてくれます。それが彼らが探しているものであるか、何かに役立つことを願っています。

0
yOshi