【发布时间】:2014-12-15 06:57:52
【问题描述】:
我有一个小表 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() 总是命中数据库。
- 启用查询缓存:没有帮助
- Marked Symbols.list() 方法@Cachable:令人惊讶的是,即使这样也不起作用。请参阅 resources.groovy。
我相信这是非常常见的用例,实现它的最佳方法是什么?一种明显的解决方案是手动缓存它,但这听起来不太好。
【问题讨论】:
-
我建议您改用 Grails 缓存插件,正如您从文档中看到的那样,它相当容易配置和使用:grails-plugins.github.io/grails-cache/guide/usage.html
-
嗨 Joshua,我已经尝试过了,请检查选项 3 和 resources.groovy;它没有用。
-
我没有看到您使用的是实际插件本身,而是使用弹簧缓存。如果您已经尝试过实际的插件,我深表歉意。我个人在这方面取得了巨大的成功。
-
你试过自动生成方法的插件吗? Symbol.list() 方法是由 grails 自动生成的,我无法使用注解。
-
我永远不会直接注释域,我会使用适当的服务层并对其进行注释。