【问题标题】:SQL/Database Views in GrailsGrails 中的 SQL/数据库视图
【发布时间】:2010-09-30 07:56:47
【问题描述】:

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

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

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

【问题讨论】:

    标签: sql database grails view


    【解决方案1】:

    您可以在 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

    【讨论】:

    • 看起来不错,谢谢!我更喜欢使用一种“虚拟”域类,但就像我说的那样,我真的怀疑在这种情况下这是否可行。
    • 多年后,仍然有效(Grails 2.0)。当查询需要本机 sql 时,很好的休眠逃生舱口。
    【解决方案2】:

    你可以把它放在你的域类映射中:

    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 刷新可以无缝地工作。

    【讨论】:

    • 在处理视图时刷新保存非常好。
    【解决方案3】:

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

    【讨论】:

    • 这似乎通常有效,但在某些情况下我遇到了一些问题。如果您想试一试,请参阅我添加到上述问题的附加链接。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 2014-10-01
    • 2012-12-07
    • 2013-10-31
    • 1970-01-01
    相关资源
    最近更新 更多