Grails中的SQL /数据库视图

时间:2009-01-08 18:17:49

标签: sql database grails view

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

是否首选创建表示视图的域类,然后我们可以对该域类使用list()?看起来这会有问题,因为Grails可能希望能够插入,更新,删除和修改任何域类的表模式。

[编辑:
在此处跟进问题:Grails Domain Class without ID field or with partially NULL composite field

3 个答案:

答案 0 :(得分: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>

我希望来源不言自明。 Documentation can be found here

答案 1 :(得分: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刷新能够很好地工作。

答案 2 :(得分:2)

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