Caching 使用二级缓存时,nhibernate查询缓存和实体缓存之间有什么区别?
我试图设置nhibernate二级缓存,并试图理解查询缓存和实体缓存之间的区别。它说你需要添加Caching 使用二级缓存时,nhibernate查询缓存和实体缓存之间有什么区别?,caching,nhibernate,fluent-nhibernate,Caching,Nhibernate,Fluent Nhibernate,我试图设置nhibernate二级缓存,并试图理解查询缓存和实体缓存之间的区别。它说你需要添加 Cache.ReadOnly(); or Cache.ReadWrite(); 在每个实体映射上,如下所示: public class CountryMap : ClassMap<country> { public CountryMap() { Table("dropdowns"); Id(x => x.Id, "pkey");
Cache.ReadOnly(); or Cache.ReadWrite();
在每个实体映射上,如下所示:
public class CountryMap : ClassMap<country>
{
public CountryMap()
{
Table("dropdowns");
Id(x => x.Id, "pkey");
Map(x => x.Name, "ddlong");
Map(x => x.Code, "dddesc");
Where("ddtype = 'COUNTRY'");
//Informing NHibernate that the Country entity itself is cache-able.
Cache.ReadOnly();
}
// xml
<class name="Country" ...>
<cache usage="read-write" region="ShortTerm" include="non-lazy/all"/>
// fluent
public CountryMap()
{
Cache.IncludeAll() // or .IncludeNonLazy
.Region("regionName")
.NonStrictReadWrite();
公共类CountryMap:ClassMap
{
公共国家地图()
{
表(“下拉列表”);
Id(x=>x.Id,“pkey”);
Map(x=>x.Name,“ddlong”);
地图(x=>x.代码,“dddesc”);
其中(“ddtype=‘国家’”);
//通知NHibernate国家实体本身是可缓存的。
Cache.ReadOnly();
}
}
但是当使用nhibernate探查器时,我看到一些东西进入了二级缓存,而我没有设置这个cache.ReadOnly()值
真的需要吗?我是否应该为每个实体都这样做(无论该实体更改的频率如何?)
如果答案是肯定的,那么我应该对所有实体执行此操作,我看到一个页面,其中提到了使用此行设置实体的风险,因为如果您尝试将该实体与查询中的其他实体联接,则可能会导致选择n+1查询问题。我使用的是nhibernate探查器,它看起来像是从下面的代码中找到了第二级缓存。在会话设置中,我有以下代码:
return configuration
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<ApplicationMap>().Conventions.Add(typeof(Conventions)))
.ExposeConfiguration(
c => {
c.SetProperty("cache.provider_class", "NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache");
c.SetProperty("cache.use_second_level_cache", "true");
c.SetProperty("cache.use_query_cache", "true");
c.SetProperty("expiration", "86400");
})
.BuildSessionFactory();
返回配置
.Mappings(m=>m.FluentMappings.AddFromAssemblyOf().Conventions.Add(typeof(Conventions)))
.曝光配置(
c=>{
c、 SetProperty(“cache.provider_class”,“NHibernate.Caches.SysCache.SysCacheProvider,NHibernate.Caches.SysCache”);
c、 SetProperty(“缓存。使用二级缓存”,“true”);
c、 SetProperty(“cache.use_query_cache”,“true”);
c、 SetProperty(“到期日”、“86400”);
})
.BuildSessionFactory();
我有一个通用的“查询”方法可以做到这一点:
ICriteria c = Session.CreateCriteria(typeof(T));
c.SetCacheable(true);
return c.Future<T>().AsQueryable();
ICriteria c=Session.CreateCriteria(typeof(T));
c、 可设置缓存(true);
返回c.Future().AsQueryable();
因此,基本上,我正在尝试确认是否正确设置了缓存,因为我在使用nhibernate profiler时看到一些二级缓存命中,但我没有在实体映射代码中设置缓存。我正在尝试确定是否需要做其他事情才能使缓存工作(或更好地工作)
当我使用nhibernate探查器时(没有在实体级别设置Cache.ReadWrite()),它似乎仍然命中了第二级缓存。(见下面的屏幕截图)
是的,您必须对所有实体执行此操作。但是,这可以通过xml配置而不是映射来完成:
我想提供一些关于NHibernate中的(第二级)缓存选项的总结。首先,有4种设置。事实上,这些确实代表了非常精细的缓存设置的真正威力
-全局开关
-全局开关
-类/实例级别.SetCacheable(true).SetCacheMode(CacheMode.Normal).SetCacheRegion(“yyy”)
-每个查询或已启用查询缓存请注意,默认情况下启用useSecondLevelCache (注意:还可以看到第一个
PropertiesHelper.GetBoolean()
调用传递最后一个默认值true
)
这意味着,如果3。设置(
)并不重要。。。所有映射的实例都将被缓存。。。非托管,默认方式
幸运的是,这不是真的。三。班级层面的设置很重要。这是必须的。没有这样的显式设置:
public class CountryMap : ClassMap<country>
{
public CountryMap()
{
Table("dropdowns");
Id(x => x.Id, "pkey");
Map(x => x.Name, "ddlong");
Map(x => x.Code, "dddesc");
Where("ddtype = 'COUNTRY'");
//Informing NHibernate that the Country entity itself is cache-able.
Cache.ReadOnly();
}
// xml
<class name="Country" ...>
<cache usage="read-write" region="ShortTerm" include="non-lazy/all"/>
// fluent
public CountryMap()
{
Cache.IncludeAll() // or .IncludeNonLazy
.Region("regionName")
.NonStrictReadWrite();
最后,我们应该在这里提到4。选项(查询级别。可设置缓存(true)
)应与二级缓存一起提供:
查询结果集也可以缓存。这仅适用于经常使用相同参数运行的查询。要使用查询缓存,必须首先启用它:
)和2)它是可配置的。事实上,我们可以使用不同的并发策略、区域、延迟加载处理。。。或者甚至不使用它们。。。这是必要的。有些实体“几乎是只读的”(例如国家代码列表),而有些实体变化很大
我们能做的最好的就是和他一起玩。试验。最后,我们可以拥有性能良好的机器。查询缓存只存储查询结果返回的实体的标识符。实际实体存储在实体缓存区域中。因此,实体必须配置为可缓存,以便与查询缓存一起使用。如果使用查询缓存时未设置实体可缓存,则仍然只有查询结果的标识符将存储在查询缓存中。正如在博客中所说的那样
查询缓存不缓存数据库中实际实体的状态
结果集;它只缓存标识符值和值的结果
类型。因此,查询缓存应始终与
二级缓存
当重新执行同一查询时,NHibernate所做的是,它从查询缓存中获取查询结果中的标识符列表,并从实体缓存中获取每个实体,如果在缓存中找不到,则从数据库中查询该元素(以多个查询结束;每个实体一个查询)
因此,始终建议
<add key="hibernate.cache.use_query_cache" value="true" />