1

我在 nhibernate.cfg.xml 文件中设置了类缓存。

当我通过 Id 获取我的实体时,一旦加载了对象,我就看不到 SQL 请求。

但是当我使用条件获取实体时,总是有 SQL 查询......

编辑:

我想这回答了我的问题:

http://www.javalobby.org/java/forums/t48846.html

假设我们想根据比直接按 ID(例如按名称)更复杂的查询来查找条目。在这种情况下,Hibernate 仍然必须发出一条 SQL 语句来获取查询的基本数据集。因此,例如,此代码:

查询 query = session.createQuery("from Person as p where p.firstName=?"); query.setString(0, "约翰"); 列表 l = query.list(); ... 将调用单个选择(假设我们的关联被缓存)。

select * from Person where firstName='John' 这个单一的选择将返回'1',然后缓存将用于所有其他查找,因为我们已经缓存了所有内容。这个强制性的单选是查询缓存的来源。

4

1 回答 1

2

不确定您的“编辑”是否意味着您已找到所有答案。NHibernate 将缓存机制分为两个区域。

第一个是“类”缓存,如上所述。任何对具有特定 ID(Session.Get(id);、引用属性、集合)的对象的请求,都可以使用类缓存。

第二个是“查询”缓存。在这种情况下,用于缓存的取决于 pass Criteria。这些用于获取结果集(where, order by, top ...)。在这种情况下缓存的是一组 ID,由该查询返回。

因此,稍后,当应用相同的条件时,将返回缓存的一组 ID,并重用来自类缓存(按 ID)的缓存实体。

(特定场景适用于投影,在最新的 NHibernate 版本中也可以缓存。在这种情况下,结果不包含具有唯一 ID 的实体,而是一组列。虽然不适合基于 ID 的缓存,但它正在工作也是。3.3 版正在为我做这件事)

所以,最后回答:

但是当我使用条件获取实体时,总是有 SQL 查询......

我们还必须允许查询缓存:

<property name="cache.use_second_level_cache">true</property>
<property name="cache.use_query_cache">true</property>

允许二级缓存,可以存储带有 ID 的对象。还启用了对查询缓存的支持,因此同一 Criteria 组合的第二次调用根本不应该转到 SQL Server。

缓存查询示例:

criteria.SetCacheable(true)
    .SetCacheMode(CacheMode.Normal)
    .SetCacheRegion("LongTerm");
于 2012-10-28T08:14:59.427 回答