Grails 中的 SQL/数据库视图
Posted
技术标签:
【中文标题】Grails 中的 SQL/数据库视图【英文标题】:SQL/Database Views in Grails 【发布时间】:2010-09-30 07:56:47 【问题描述】:有谁知道通过 Grails 访问 sql 视图的最佳方法是什么(或者这是否可能)?这样做的一个明显方法是对视图使用 executeQuery 从视图中选择一组行,我们不会将其视为域对象列表。然而,即使在这种情况下,对哪个域类运行 executeQuery 也并不明显,因为实际上我们只是使用该域类来针对完全不相关的实体(视图)运行查询。
是否最好创建一个表示视图的域类,然后我们可以针对该域类使用 list()?这似乎会出现问题,因为 Grails 可能希望能够插入、更新、删除和修改任何域类的表模式。
[编辑: 在这里跟进问题:Grails Domain Class without ID field or with partially NULL composite field
【问题讨论】:
【参考方案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 会打印一些关于无法执行插入、删除等操作的日志消息,但它不会抛出任何错误,除非您实际上尝试执行除域类查询之外的其他操作。
【讨论】:
这似乎通常有效,但在某些情况下我遇到了一些问题。如果您想试一试,请参阅我添加到上述问题的附加链接。谢谢!以上是关于Grails 中的 SQL/数据库视图的主要内容,如果未能解决你的问题,请参考以下文章
一旦AngularJs中的数据库发生变化,如何实现自动视图更新?