Hibernate Criteriaクエリ - Criteria.createAliasで関連副問い合わせ
2008/10/09 16:49Update
Hibernate Criteriaクエリは、Criteria.createCriteriaやCriteria.createAliasメソッドで関連エンティティに問い合わせができます。本文は、Criteria.createAliasの使い方やCriteria.createCriteriaとの相違点について学びます。
※関連副問い合わせ:指定する条件で、関連しあうエンティティ同士へ問い合わせを行います。
「Hibernate Criteriaクエリ - Criteria.createCriteriaで関連副問い合わせ
」 という記事で、Criteria.createCriteriaで関連副問い合わせについて学びました。本文は、Criteria.createAliasを学びます。
Criteria.createAliasのAPI仕様について次のページにてご確認できます。
org.hibernate.Criteria
Criteria createAlias(String associationPath, String alias)
Criteria createAlias(String associationPath, String alias, int joinType)
では、サンプルから始めます。
■サンプル
これはCriteria.createAliasの基本的な使い方です。
①ROOTクエリの条件を設定します:cat.name like 'F%'
②Cat.kittensをktというエイリアス(別名)で返します。
③ktに対して条件を設定します:kt.name like 'KT%'
④戻り値はList<Cat>コレクションになります。
Criteriaクエリでは、関連問い合わせを行うには、関連を表す定義をマッピング設定ファイルに記述しなければなりません。
上のサンプルの場合、次のように定義する必要があると考えられます。
Cat.java
Cat.hbm.xml
本題に戻ります。
上のサンプル1)で関連エンティティに対して条件を指定してにもかかわらず、実際に返された結果をのぞいてみると、Catと関連したすべてのkittensが返されています。
条件に合致する関連エンティティを取得するには、Criteria.setResultTransformerを使う必要があります。
詳細は次の記事をご参照ください。
Hibernate Criteriaクエリ - Criteria.createCriteriaで関連副問い合わせ
Criteria.createAliasの使い方はCriteria.createCriteriaと似ていますが、違いところがあります。
サンプルから見てみしましょう。
実際に実行したところ、次のようなログが出力されます。
Hibernate: select this_.ID as ID2_, this_.NAME as NAME0_2_, son1_.id as id0_, son1_.NAME as NAME1_0_, son1_.FATHER_ID as FATHER3_1_0_, father4_.ID as ID1_, father4_.NAME as NAME0_1_ from FATHER this_ inner join SON son1_ on this_.ID=son1_.FATHER_ID left outer join FATHER father4_ on son1_.FATHER_ID=father4_.ID where this_.NAME like ? and son1_.NAME like ?
6
Hibernate: select this_.ID as ID2_, this_.NAME as NAME0_2_, son1_.id as id0_, son1_.NAME as NAME1_0_, son1_.FATHER_ID as FATHER3_1_0_, father4_.ID as ID1_, father4_.NAME as NAME0_1_ from FATHER this_ inner join SON son1_ on this_.ID=son1_.FATHER_ID left outer join FATHER father4_ on son1_.FATHER_ID=father4_.ID where this_.NAME like ? and this_.NAME like ?
0
ログを見れば明白です。Criteria.createAliasの場合、
こうなると、予想通りのSQLを発行してくれます。
Hibernate: select this_.ID as ID2_, this_.NAME as NAME0_2_, son1_.id as id0_, son1_.NAME as NAME1_0_, son1_.FATHER_ID as FATHER3_1_0_, father4_.ID as ID1_, father4_.NAME as NAME0_1_ from FATHER this_ inner join SON son1_ on this_.ID=son1_.FATHER_ID left outer join FATHER father4_ on son1_.FATHER_ID=father4_.ID where this_.NAME like ? and son1_.NAME like ?
※Criteria.createCriteriaは新しいCriteriaインスタンスを作成して利用するのに、Criteria.createAliasは新しいCriteriaインスタンスを利用しません。
org.hibernate.Criteriaの実装クラス
org.hibernate.impl.CriteriaImpl#
org.hibernate.impl.Subcriteria#
org.hibernate.impl.Subcriteria#
「Hibernate Criteriaクエリ - Criteria.createCriteriaで関連副問い合わせ
」 という記事で、Criteria.createCriteriaで関連副問い合わせについて学びました。本文は、Criteria.createAliasを学びます。Criteria.createAliasで関連副問い合わせ
Criteria.createAliasのAPI仕様について次のページにてご確認できます。
org.hibernate.Criteria

Criteria createAlias(String associationPath, String alias)
Criteria createAlias(String associationPath, String alias, int joinType)
では、サンプルから始めます。
■サンプル
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%") ) //①
.createAlias("kittens", "kt") //②
.add( Restrictions.like("kt.name", "KT%") ) //③
.list(); //④
これはCriteria.createAliasの基本的な使い方です。
①ROOTクエリの条件を設定します:cat.name like 'F%'
②Cat.kittensをktというエイリアス(別名)で返します。
③ktに対して条件を設定します:kt.name like 'KT%'
④戻り値はList<Cat>コレクションになります。
Criteriaクエリでは、関連問い合わせを行うには、関連を表す定義をマッピング設定ファイルに記述しなければなりません。
上のサンプルの場合、次のように定義する必要があると考えられます。
Cat.java
public class Cat {
private java.util.Set kittens;
...
Cat.hbm.xml
<hibernate-mapping> <class name="Cat" table="CAT"> ... <set name="kittens" ...> ... <one-to-many ... /> </set> </class> </hibernate-mapping>
本題に戻ります。
上のサンプル1)で関連エンティティに対して条件を指定してにもかかわらず、実際に返された結果をのぞいてみると、Catと関連したすべてのkittensが返されています。
条件に合致する関連エンティティを取得するには、Criteria.setResultTransformerを使う必要があります。
詳細は次の記事をご参照ください。
Hibernate Criteriaクエリ - Criteria.createCriteriaで関連副問い合わせ
Criteria.createAlias と Criteria.createCriteriaの相違点
Criteria.createAliasの使い方はCriteria.createCriteriaと似ていますが、違いところがあります。
サンプルから見てみしましょう。
//①クエリ1:createCriteria
List<Father> fatherList = (List<Father>) sess.createCriteria(Father.class)
.add(Restrictions.like("name", "f%"))
.createCriteria("sonSet")
.add(Restrictions.like("name", "s%")) //sonSet.name like 's%'
.list();
System.out.println(fatherList.size());
//②クエリ2:createAlias
fatherList = (List<Father>) sess.createCriteria(Father.class)
.add(Restrictions.like("name", "f%"))
.createAlias("sonSet", "son")
.add(Restrictions.like("name", "s%")) //father.name like 's%'
.list();
System.out.println(fatherList.size());
実際に実行したところ、次のようなログが出力されます。
Hibernate: select this_.ID as ID2_, this_.NAME as NAME0_2_, son1_.id as id0_, son1_.NAME as NAME1_0_, son1_.FATHER_ID as FATHER3_1_0_, father4_.ID as ID1_, father4_.NAME as NAME0_1_ from FATHER this_ inner join SON son1_ on this_.ID=son1_.FATHER_ID left outer join FATHER father4_ on son1_.FATHER_ID=father4_.ID where this_.NAME like ? and son1_.NAME like ?
6
Hibernate: select this_.ID as ID2_, this_.NAME as NAME0_2_, son1_.id as id0_, son1_.NAME as NAME1_0_, son1_.FATHER_ID as FATHER3_1_0_, father4_.ID as ID1_, father4_.NAME as NAME0_1_ from FATHER this_ inner join SON son1_ on this_.ID=son1_.FATHER_ID left outer join FATHER father4_ on son1_.FATHER_ID=father4_.ID where this_.NAME like ? and this_.NAME like ?
0
ログを見れば明白です。Criteria.createAliasの場合、
fatherList = (List<Father>) sess.createCriteria(Father.class)
.add(Restrictions.like("name", "f%"))
.createAlias("sonSet", "son")
.add(Restrictions.like("son.name", "s%")) //ここ エイリアスsonで明示的に制限する必要があります
.list();
こうなると、予想通りのSQLを発行してくれます。
Hibernate: select this_.ID as ID2_, this_.NAME as NAME0_2_, son1_.id as id0_, son1_.NAME as NAME1_0_, son1_.FATHER_ID as FATHER3_1_0_, father4_.ID as ID1_, father4_.NAME as NAME0_1_ from FATHER this_ inner join SON son1_ on this_.ID=son1_.FATHER_ID left outer join FATHER father4_ on son1_.FATHER_ID=father4_.ID where this_.NAME like ? and son1_.NAME like ?
※Criteria.createCriteriaは新しいCriteriaインスタンスを作成して利用するのに、Criteria.createAliasは新しいCriteriaインスタンスを利用しません。
org.hibernate.Criteriaの実装クラス
org.hibernate.impl.CriteriaImpl#
org.hibernate.impl.Subcriteria#
//抜粋...
public Criteria createAlias(String associationPath, String alias)
throws HibernateException {
new Subcriteria(this, associationPath, alias);
return this;
}
public Criteria createCriteria(String associationPath)
throws HibernateException {
return new Subcriteria(this, associationPath);
}
public Criteria createCriteria(String associationPath, String alias)
throws HibernateException {
return new Subcriteria(this, associationPath, alias);
}
org.hibernate.impl.Subcriteria#
//抜粋...
private Subcriteria(Criteria parent, String path, String alias) {
this.alias = alias;
this.path = path;
this.parent = parent;
subcriteriaList.add(this);
}
private Subcriteria(Criteria parent, String path) {
this(parent, path, ((String) (null)));
}
Sponsored Link
Comments
- Relative Articles
- Hibernate設定ファイルその1 - hibernate.cfg.xml - (2008/07/09 14:08)
- Hibernate c3p0 - よく利用されているコネクションプーリング - (2008/07/09 15:00)
- Hibernate 方言(Dialect)一覧 - (2008/07/09 15:10)
- Hibernate のSessionとSessionFactory - (2008/07/09 15:51)
- ThreadLocal でHibernate Session を効率的に管理する - (2008/07/09 18:43)
- Hibernateで複数のDBに接続するには? - (2008/07/09 18:47)
- Hibernateとは - (2008/07/11 14:23)
- Hibernate のインストール - (2008/07/24 11:01)
- Hibernate の開発手順 - (2008/07/24 12:44)
- Hibernate SQLをログに出力方法 - (2008/07/30 16:06)