Grails Hibernate 过滤器 findById(id) 与 get(id)

use*_*091 4 grails grails-plugin

我正在使用 hibernate Filter 根据登录来过滤我的域类。

它正在按预期工作

<DomainClass>.findById(<id>)
Run Code Online (Sandbox Code Playgroud)

但它不适合

<DomainClass>.get(<id>).
Run Code Online (Sandbox Code Playgroud)

为什么 get 的第二个版本不使用过滤器?

vic*_*orf 6

嗯,我找到了伯特几年前对这个问题所做的具体解释。

get()(和read(),使用get()实例并将其设置为只读)是唯一始终使用二级缓存的方法。load()也会,但它没有映射到 GORM 中。所有其他方法都是标准查询或 HQL 查询的变体,它们支持使用查询缓存(与使用的实例缓存分开get()),但默认情况下不使用它。

这很容易测试。在 DataSource.groovy 中打开基本 sql 日志记录:

dataSource {
   pooled = true
   driverClassName = ...
   ...
   loggingSql = true
}
Run Code Online (Sandbox Code Playgroud)

并创建一个简单的缓存类:

class Thing {
      String name
      static mapping = {
         cache true
      }
   }
Run Code Online (Sandbox Code Playgroud)

运行grails console并创建一个实例:

def thing = new Thing(name: 'foo').save()
Run Code Online (Sandbox Code Playgroud)

然后使用 findById() 加载它,并注意重复调用每次都会生成 SQL:

println Thing.findById(1L).name
Run Code Online (Sandbox Code Playgroud)

并使用 get() 加载它,并注意只有第一次调用会生成 SQL,而重复调用则不会:

println Thing.get(1L).name
Run Code Online (Sandbox Code Playgroud)

然后您可以findById()再次调用,即使该实例已被缓存,它每次仍然会访问数据库。”

就我而言,它的工作原理完全像这样。

  • 感谢维克多所做的一切努力。我现在所做的是将所有控制器中的所有“.get(”替换为“.findById(”),并手动检查每个替换。 (2认同)