28

Grails を介して SQL ビューにアクセスするための最良の方法を知っている人はいますか (または、これが可能な場合)? これを行う明白な方法は、ビューに対して executeQuery を使用して、ドメイン オブジェクトのリストとして扱わないビューから行のコレクションを選択することです。ただし、この場合でも、まったく無関係なエンティティ (ビュー) に対してクエリを実行するためにそのドメイン クラスを使用しているだけなので、どのドメイン クラスに対して executeQuery を実行するかは明らかではありません。

ビューを表すドメイン クラスを作成し、そのドメイン クラスに対して list() を使用するだけでよいでしょうか? Grails はおそらく、任意のドメイン クラスのテーブル スキーマを挿入、更新、削除、および変更できると想定しているため、これには問題があるようです。

[編集:
フォローアップの質問: Grails Domain Class without ID field or with partial NULL composite field

4

3 に答える 3

34

ビューに好ましい方法でアクセスする場合(IMO)、GrailsでプレーンSQLを使用できます。

たとえば、コントローラーで:

import groovy.sql.Sql

class MyFancySqlController {

    def dataSource // the Spring-Bean "dataSource" is auto-injected

    def list = {
        def db = new Sql(dataSource) // Create a new instance of groovy.sql.Sql with the DB of the Grails app

        def result = db.rows("SELECT foo, bar FROM my_view") // Perform the query

        [ result: result ] // return the results as model
    }

}

そしてビュー部分:

<g:each in="${result}">
    <tr>
        <td>${it.foo}</td>
        <td>${it.bar}</td>
    </tr>
</g:each>

ソースが自明であることを願っています。ドキュメントはここにあります

于 2009-01-08T18:38:29.213 に答える
4

これをドメイン クラス マッピングに入れることができます。

static mapping = {
    cache 'read-only'
}

しかし、それがビューであることをHibernateが理解するのに役立つかどうかはわかりません... http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-cache-readonly

とにかく、現在のプロジェクトでは、データベース ビューを Grails ドメイン クラスとしてよく使用します。HQL は厄介であり、SQL を使用してテーブルを結合する方が簡単だからです。

ただし、注意する必要があるのは、Hibernate のクエリのバッチ処理 (およびフラッシュ ビジネス全体) です。テーブルに何かを挿入し、同じトランザクションでそのテーブルに依存するビューを選択すると、挿入した最新の行は取得されません。これは、Hibernate が実際にはまだ行を挿入していないためです。一方、行を挿入したテーブルを選択した場合、Hibernate は選択の結果を提供する前に保留中のクエリをフラッシュする必要があると判断します。

1 つの解決策は、ドメイン インスタンスを保存するときに ( flush:true) を実行することです。その後、同じトランザクションでビュー全体を読み取る必要があることがわかっています。

ただし、ビュー/ドメインが他のどのドメインクラスに依存するかを Hibernate に伝える何らかの方法があれば、Hibernate のフラッシュが問題なくうまく機能するようになります。

于 2009-07-21T23:12:56.713 に答える
2

通常のテーブルのように扱うだけで、ドメイン クラスをビューにマップすることは完全に可能です。Grails は、挿入や削除などを実行できないというログ メッセージを出力すると思いますが、ドメイン クラスでクエリ以外のことを実際に実行しようとしない限り、エラーは発生しません。

于 2009-01-09T11:01:54.080 に答える