0

グループと呼んだクラスの階層を構築しようとしています。ドメインはかなり単純です。

class SubGroup implements Serializable {
    Group child
    Group parent

    static mapping = {
        id composite: ['child', 'parent']
    }
}

class Group implements Serializable {           
    int groupId
    String key
    String title

    static mapping = {
        id name: 'groupId'
    }
}

基本的に、グループの親とそれに関連する子のマップを作成したいと思います。そのため、各レコードをループ処理し (Map をクエリするためのよりクリーンな方法があれば、それを聞いてうれしいです)、そのためのマップ エントリを作成します。

Map hierarchy = [:]
SubGroup.list().each { relation ->
    if (!hierarchy[relation.parent]) {
        hierarchy[relation.parent] = new HashSet()
    }

    hierarchy[relation.parent] << relation.child
}

休止状態は、次のような単純なクエリを使用すると思います。

select * from sub_group s, group c, group p 
where s.child_id = c.group_id and s.parent_id = p.group_id

しかし、それは結合を行っていません。サブグループのクエリに続いて、グループ テーブルの n 個のクエリを実行しています (N+1 選択問題)。うーん。2.0 では休止状態のクエリ キャッシュに問題があると聞いたので、無効にしました。lazy: falsefetch: joinを親と子の両方の列の SubGroup ドメイン クラスに追加しようとしましたが、うまくいきませんでした。list メソッドに(fetch: [child: 'eager'])をパラメーターとして追加してみました。結合は行いません。何か不足していますか?正直に言うと、後でキー プロパティとタイトル プロパティの両方が必要になりますが、groupId 外部キー プロパティにアクセスするだけなので、実際には結合を行う必要さえありません。

もちろん、子と親のプロパティを int にして、残りのデータが必要なときに独自のクエリを実行するか、HQL やその他の方法を使用してこれを単一のクエリに制限することもできますが、GORM はそうすべきだと思われます私のためにこれをしている。ご協力いただきありがとうございます。
よろしく、

ジム

4

1 に答える 1

0

以下に示すように、listメソッドを使用するのではなく、Hibernateが子と親ごとにselect呼び出しを行わずにこれを機能させる唯一の方法は、代わりにHQLクエリを実行することでした。

Map hierarchy = [:]
def subGroups = SubGroup.executeQuery("SELECT s.parent, s.child FROM SubGroup s")
subGroups.each { relation ->
    if (!hierarchy[relation[0]]) {
        hierarchy[relation[0]] = new HashSet()
    }

    hierarchy[relation[0]] << relation[1]
}

したがって、実際には、関係を定義するためにSubGroupドメインクラスのみを使用しています。なんらかのマッピングでこれができるはずだと思いますが、どうすればいいのかわかりませんでした。

于 2012-11-20T23:04:09.843 に答える