gpt4 book ai didi

hibernate - 如何在grails中缓存(整个表或Domain.list()方法的结果)?

转载 作者:行者123 更新时间:2023-12-02 13:51:33 25 4
gpt4 key购买 nike

我有一个小表SYMBOLS,用于填充ui上的下拉列表。由于此表主要包含静态数据,因此我想缓存其内容。

我的问题是,每次调用Symbol.list()方法时,都会在数据库上执行查询。

域类:

package com.perseus.ui.model

class Symbol implements Serializable, Comparable<Symbol> {

private static final long serialVersionUID = 1L;

String exchange
String symbol
String description
int index

static constraints = {
exchange(nullable:false, blank: false)
symbol(nullable:false, blank: false)
description(nullable:false, blank: false)
}

static mapping = {
id composite: ['exchange', 'symbol']
table 'Symbols'
cache 'read-only'
}

String toString() {
return description
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((exchange == null) ? 0 : exchange.hashCode());
result = prime * result + ((symbol == null) ? 0 : symbol.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Symbol other = (Symbol) obj;
if (exchange == null) {
if (other.exchange != null)
return false;
} else if (!exchange.equals(other.exchange))
return false;
if (symbol == null) {
if (other.symbol != null)
return false;
} else if (!symbol.equals(other.symbol))
return false;
return true;
}

@Override
public int compareTo(Symbol o) {
int result = 0
if(this.index)
result = -1
else if(o.index) {
result = 1
} else {
result = this.symbol.compareTo(o.symbol)
}
return result;
}


}

resources.groovy
// Place your Spring DSL code here
beans = {
xmlns cache: 'http://www.springframework.org/schema/cache'
xmlns aop: 'http://www.springframework.org/schema/aop'

importBeans('classpath:config/beans.xml')

cache.'advice'(id: 'symbolCacheAdvice',
'cache-manager': 'grailsCacheManager') {
caching(cache: 'symbols') {
cacheable(method: 'list')
}
}

aop.config {
advisor('advice-ref': 'symbolCacheAdvice',
pointcut: 'execution(* com.perseus.ui.model.Symbol.*(..))')
}

}

用户界面元素: <g:select name="symbol" from="${Symbol.list(readOnly: true)}" optionKey="symbol" />
我尝试了以下选项,但它们似乎都不起作用:
  • 休眠第二级缓存:缓存了对象,但是Symbol.list()总是命中数据库。
  • 启用查询缓存:不利于
  • 标记Symbols.list()方法@Cachable:令人惊讶的是,这甚至行不通。请参阅resources.groovy。

  • 我认为这是非常常见的用例,实现此目的的最佳方法是什么?一种明显的解决方案是手动缓存它,但这听起来不太好。

    最佳答案

    通常,请避免对GORM查询结果使用缓存插件-Hibernate的第一级和第二级缓存非常可靠,并且可以防止陈旧数据,因为当有可能这些结果可能受到更改的影响时,它们会刷新缓存的数据。但是,如果您直接使用Ehcache或诸如Spring Cache或Grails插件之类的包装API,则必须知道何时使数据无效,这可能是一个难题。

    如果您计划仅通过list()方法访问缓存的数据(这是有意义的,因为它们全部都在内存中),那么您需要使用查询缓存的变体,并且必须在DataSource.groovy中启用它:

    hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = true
    ...
    }
    list()没有缓存选项,您可以运行具有以下条件的等效条件查询:
    def symbols = Symbol.createCriteria().list {
    cache true
    }

    如果要按ID访问项目,请运行查询以获取所有ID,然后在启动时循环遍历,并为每个ID调用 Symbol.get(id)。各个实例都缓存在自己的缓存中,而不是查询缓存中,因此不太可能导致早期失效。

    还要注意,您需要配置基础缓存实现,并配置缓存大小,内存中的元素,溢出到磁盘等。Ehcache中的默认TTL为120秒-仅2分钟。但是,如果您很少或从未编辑/创建/删除这些文件,则可以根据需要进行缓存。

    关于hibernate - 如何在grails中缓存(整个表或Domain.list()方法的结果)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26463189/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com