Hibernate Criteriaクエリ - Criteria.createAliasで関連副問い合わせ

2008/10/09 16:49Update
TAGS: Hibernate | Criteriaクエリ | createAlias

Hibernate Criteriaクエリは、Criteria.createCriteriaやCriteria.createAliasメソッドで関連エンティティに問い合わせができます。本文は、Criteria.createAliasの使い方やCriteria.createCriteriaとの相違点について学びます。

※関連副問い合わせ:指定する条件で、関連しあうエンティティ同士へ問い合わせを行います。

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

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments

用户名 (required)

Email (will not be published) (required)

URL

Evaluation