默认使用 hibernate/ehcache 缓存所有查询?

问题描述 投票:0回答:3

我们的应用程序处理只读数据,因此我们正在考虑在所有查询上使用 Hibernate 查询缓存功能(由 ehcache 实现)。

到目前为止,我们启用了二级缓存和查询缓存:

<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>

然后告诉hibernate每个查询都是可缓存的:

query.setHint("org.hibernate.cacheable", true);

我可以发现这种方法的两个缺点:

  • 代码冗余(因为您必须手动为每个查询添加提示)

  • hibernate 依赖项(到目前为止,代码是直接干净的
    hibernate 引用,仅使用 JPA 注释)

有什么方法可以实现这一点,即仅使用配置文件缓存所有查询?

谢谢!

hibernate caching ehcache second-level-cache query-cache
3个回答
1
投票

不,没有,因为这没有多大意义(或者更好地说,它在 99.99% 的用例中没有用)。

对于查询和输入参数(绑定变量)的每个组合,缓存中始终有一个不同的条目。

对于从很少更改(插入、更新、删除)的实体(表)中选择的查询,并且不会有大量不同输入参数的组合,应启用查询缓存。


0
投票

在我的应用程序中能够缓存所有查询是有意义的。我的应用程序又大又旧,即使在同一个事务中,它最终也会重复大量查询。如果该应用程序可以在请求期间缓存所有查询的查询结果,那么该应用程序将运行得更快,并且不会使用更多内存。为了简化起见,我将缓存设置为 10 秒,然后我的应用程序将显着加快。


0
投票

接受的答案不正确。 许多应用程序需要缓存 100% 的命名查询。 我知道的所有应用程序都将受益于默认缓存所有内容和一些排除给定查询的提示。

因此,在没有请求的默认值的情况下,在 ehcache/hibernate 中启用查询缓存后,您需要将此提示添加到所有查询中:

@NamedQuery(name = "OrderState.findByFqn", query = "select os from OrderState os where os.fqn = ?1", hints = @QueryHint(name = "org.hibernate.cacheable", value = "true")),

然后关键是测试,很多小事情都可以破坏真正的ehcaching。 “真实”不仅意味着 PK,还意味着所有对象属性/嵌套属性等...因此,您只需添加此 hiberante 拦截器,使用系统测试/公共静态标志将其打开,然后由 hibernate 生成的任何 SQL数据库将抛出一个错误,您可以捕获该错误并将其显示在您的 Web UI 中:

public class SqlCommentStatementInspector implements StatementInspector {
 
public static final String UNEXPECTED_SQL_GENERATED_MESSAGE = "UNEXPECTED SQL GENERATED";

private static final Log log = LogFactory.getLog(SqlCommentStatementInspector.class);


@Override
public String inspect(String sql) {
        
    if(StringUtils.isNotEmpty(sql) && SystemTest.ERROR_ON_SQL_B)
        throw new RuntimeException(UNEXPECTED_SQL_GENERATED_MESSAGE + ": " + sql);
    else
        return sql;       
}

}

Spring 无法配置拦截器

© www.soinside.com 2019 - 2024. All rights reserved.