私は2つのテーブルを持っています-1つは住所を含み、もう1つは写真を含みます。それらの間の唯一の共通フィールドはPersonIDです。これらは、2つのPOJOクラスのアドレスと写真にマップされました。条件を作成し、フィールドに制限を追加することで、これらのテーブルの詳細を取得することができました。 2つのテーブルに結合をどのように記述すればよいですか。住所と写真の2つのオブジェクトとして結果を取得することは可能ですか?.
写真のない人の記録も取れるように、左結合をしたいです。これはhqlを使用してのみ可能であると読みましたが、基準を使用してこれを行うこともできますか?
シータ結合を使用して、結果を2つのオブジェクトとして返すHQLクエリを簡単に記述できます(エイドリアンが指摘したように)。次に例を示します。
String queryText = "select address, photo from Address address, Photo photo "
+ " where address.personID=photo.personId";
List<Object[]> rows = session.createQuery(queryText).list();
for (Object[] row: rows) {
System.out.println(" ------- ");
System.out.println("Address object: " + row[0]);
System.out.println("Photo object: " + row[1]);
}
ご覧のとおり、クエリはフェッチされた各行を表すObject []配列のリストを返します。この配列の最初の要素には、1つのオブジェクトと2番目の要素(別の要素)が含まれます。
編集:
左結合の場合、ネイティブSQLクエリ(HQLクエリではない)を使用する必要があると思います。これを行う方法は次のとおりです。
String queryText = "select address.*, photo.* from ADDRESS address
left join PHOTO photo on (address.person_id=photo.person_id)";
List<Object[]> rows = sess.createSQLQuery(queryText)
.addEntity("address", Address.class)
.addEntity("photo", Photo.class)
.list();
これはあなたのケースでうまくいくはずです。
この記事 で説明したように、2つのオプションがあります。
Hibernate 5.1以降、無関係のエンティティには アドホック結合 を使用できます。
Tuple postViewCount = entityManager.createQuery(
"select p as post, count(pv) as page_views " +
"from Post p " +
"left join PageView pv on p.slug = pv.slug " +
"where p.title = :title " +
"group by p", Tuple.class)
.setParameter("title", "High-Performance Java Persistence")
.getSingleResult();
Hibernate 5.1より前は、シータスタイルの結合しか使用できませんでした。ただし、シータスタイルの結合は等結合と同等であるため、エミュレートできるのは内部結合のみであり、外部結合はエミュレートできません。
List<Tuple> postViewCount = entityManager.createQuery(
"select p as post, count(pv) as page_views " +
"from Post p, PageView pv " +
"where p.title = :title and " +
" ( p.slug = pv.slug ) " +
"group by p", Tuple.class)
.setParameter("title", "Presentations")
.getResultList();
詳細については、 この記事 をご覧ください。
最後に12年後、Hibernateチームは そのような機能を実装しました
From Hibernate docs :
FROM句には、joinキーワードを使用した明示的な関係結合を含めることもできます。これらの結合は、内側または左外側のスタイルの結合にすることができます。
List<Person> persons = entityManager.createQuery(
"select distinct pr " +
"from Person pr " +
"join pr.phones ph " +
"where ph.type = :phoneType", Person.class )
.setParameter( "phoneType", PhoneType.MOBILE )
.getResultList();
List<Person> persons = entityManager.createQuery(
"select distinct pr " +
"from Person pr " +
"left join pr.phones ph " +
"where ph is null " +
" or ph.type = :phoneType", Person.class )
.setParameter( "phoneType", PhoneType.LAND_LINE )
.getResultList();
または、WITH
およびON
キーワードを使用できます。それらについての意見
重要な違いは、HQL/JPQL条件がWHEREの一部になっているこのセクションの他のクエリとは対照的に、生成されたSQLではWITH/ON句の条件が生成されたSQLのON句の一部になっていることです。生成されたSQLの句。
例
List<Object[]> personsAndPhones = session.createQuery(
"select pr.name, ph.number " +
"from Person pr " +
"left join pr.phones ph with ph.type = :phoneType " )
.setParameter( "phoneType", PhoneType.LAND_LINE )
.list();
私は現在、新機能を試してみたいと思っています。
Hibernate 5.1では、関連のない2つのエンティティを結合できます。
例:
select objA from ObjectA objA
JOIN ObjectB objB on objB.variable = objA.variable
where objA.id = 1
あなたが探しているのは
(質問が最初に行われ、この回答が与えられたとき) Hibernateは、1を実行できるThetaJoinをサポートしています。 &2。ただし、シータ結合スタイルで使用できるのは内部結合のみです。
個人的には、適切な関係をモデル化することをお勧めします。そのため、HQLで十分にサポートされている1と3が必要です。
(別の回答は、実際にそのような機能を提供する新しいHibernate機能の更新を提供しました。これは単に参照することができます)
参加したいクラスを含むクラスを作成して、それらをすべてまとめることをお勧めします。
ただし、たまにしかこれらのテーブルを結合しない場合は、基準を使用して、各テーブルからデータを手動でロードし、それらをまとめることができます。 (はい、住所と写真に2つの別々のクラスとテーブルがある場合は、これらのテーブルのデータを別々に持つことができます)