28

有谁知道通过 Grails 访问 sql 视图的最佳方法是什么(或者这是否可能)?这样做的一个明显方法是对视图使用 executeQuery 从视图中选择一组行,我们不会将其视为域对象列表。然而,即使在这种情况下,对哪个域类运行 executeQuery 也并不明显,因为实际上我们只是使用该域类来针对完全不相关的实体(视图)运行查询。

是否更愿意创建一个表示视图的域类,然后我们可以对那个域类使用 list() ?这似乎会出现问题,因为 Grails 可能希望能够插入、更新、删除和修改任何域类的表模式。

[编辑:
在此跟进问题:Grails Domain Class without ID field or with partial NULL complex field

4

3 回答 3

34

您可以在 Grails 中使用普通 SQL,这是在以首选方式访问视图的情况下(IMO):

例如在您的控制器中:

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 会发现它需要在为您提供选择结果之前刷新其挂起的查询。

一种解决方案是 ( flush:true) 在保存域实例时,您知道以后需要在同一事务中通读视图。

然而,如果有某种方式告诉 Hibernate 一个视图/域依赖于哪些其他域类,那就太酷了,这样 Hibernate 刷新可以无缝地工作。

于 2009-07-21T23:12:56.713 回答
2

完全可以将域类映射到视图,只需将其视为常规表即可。我认为 Grails 会打印一些关于无法执行插入、删除等操作的日志消息,但它不会抛出任何错误,除非您实际上尝试执行域类查询以外的操作。

于 2009-01-09T11:01:54.080 回答