二级缓存

1、优点

 (1)、维护方便:SqlSugar的 二级缓存 支持单表和多表的 CRUD 自动缓存更新 ,减少了复杂的缓存KEY维护操作

 (2)、使用方便:可以直接在Queryable.WithCache直接缓存当前对象

 (3)、外部集成: 通过实现ICacheService接口,来调用外部缓存方法,想用什么实现什么

2、原理与性能

2.1 原理

二级缓存是将结果集进行缓存,当SQL和参数没发生变化的时候从缓存里面读取数据,减少数据库的读取操作

注意:Sql语句一直在变的就不适合缓存,比如 ID=?这种SQL都在变化,并且?的数量巨大这种情况就不要使用缓存了,缓存适合加

在Sql和参数的值相对固定查询语句上面,数量不多可以一次性全部查出来,下次直接内存操作

验证: 一个正常的系统同时存在的缓存Key应该在 1000个以下,如果超过这个数量说明很多地方缓存用的不当

2.2 性能优化 new

上面虽然介绍了避免Key太多,但是还是会有人会使用大量key,我们可重写模糊删除缓存方法避免使用

Service.GetAllKey()

 //5.1.4.109-preview06+
 //程序启动时重写模糊删除缓存方法
 StaticConfig.CacheRemoveByLikeStringFunc = (service, key) =>
 {
    //根据key模糊删除缓存  
 };


3、创建

创建一个继承ICacheService的缓存类 SqlSugarRedisCache,然后配置到服务设置(具体怎么建看标题5

  ICacheService myCache = new SqlSugarRedisCache();//这个类如何建看标题5
  SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
  {
                ConnectionString = Config.ConnectionString,
                DbType = DbType.SqlServer,
                IsAutoCloseConnection = true,
                ConfigureExternalServices = new ConfigureExternalServices()
                {
                    DataInfoCacheService = myCache //配置我们创建的缓存类,具体用法看标题5
                }
   });

4、查询使用缓存

 4.1 自动key模式

原理:根据生成的Sql语句作为缓存KEY

//语句1
db.Queryable<Student>().Where(it => it.Id > 0).WithCache().ToList();//设置缓存默认一天
//语句2
db.Queryable<Student>().WithCache(1000).ToList();//设置具体过期时间
//语句3
db.Queryable<Student, School, DataTestInfo>((st, sc, di) => new JoinQueryInfos(
              JoinType.Left,st.SchoolId==sc.Id, 
              JoinType.Left,st.Name==di.String
            ))
           .WithCache() //多表操作
           .Select<ViewModelStudent>().ToList();
           
//语法糖
Queryable.WithCacheIF(bool) 
//等同于下面代码 
if(bool)
{
  Queryable.WithCache()
}
//删除缓存看4.3

 4.2 追加key模式

原理:sql+追加的key (5.0.3.8+

var list=Queryable<Student>().WithCache("MyCackey").ToList()//缓存数据

//清空缓存方式
db.DataCache.RemoveDataCache("MyCackey"); //方式1 
db.Deleteable<Student>().RemoveDataCache("MyCackey").Where(it => it.Id == 1).ExecuteCommand(); //方式2

 4.3 清空缓存

//1.半自动清空缓存 :
//当student表发生删除操作,并且删除操作用了RemoveDataCache,那么查询语句1、语句2和语句3 都会清空缓存 
db.Deleteable<Student>().RemoveDataCache().Where(it => it.Id == 1).ExecuteCommand();//只支持实体
//插入和更新一样用法


//2.全自动清理:
//所有 增、删 、改 会自动调用.RemoveDataCache()
ConnectionString = Config.ConnectionString,
IsAutoCloseConnection = true,
MoreSettings = new ConnMoreSettings() {
   IsAutoRemoveDataCache = true
}
//缺点:
//基本单表查询和联表查询都支持,如果用到子查询或者Mergetable就无法自动清除了,这种情况用 【4.2追加key模式】


//3.根据Key关键词清空
db.DataCache.RemoveDataCache("MyCackey"); //比如缓存KEY带有MyCackey关键词的全部清空


5、实现接口

我们需要创建一个 "SqlSugarRedisCache"  继承  ICacheService

public class SqlSugarRedisCache : ICacheService
    {
    
      //NUGET安装 SugarRedis  (也可以自个实现)   
      //注意:SugarRedis 不要扔到构造函数里面, 一定要单例模式  
      public static SugarRedisClient _service = new SugarRedisClient();
      
      
      //+1重载 new SugarRedisClient(字符串)
      //默认:127.0.0.1:6379,password=,connectTimeout=3000,connectRetry=1,syncTimeout=10000,DefaultDatabase=0

        public void Add<V>(string key, V value)
        {
            _service.Set(key, value);
        }

        public void Add<V>(string key, V value, int cacheDurationInSeconds)
        {
            _service.SetBySeconds(key, value, cacheDurationInSeconds);
        }

        public bool ContainsKey<V>(string key)
        {
            return _service.Exists(key);
        }

        public V Get<V>(string key)
        {
            return _service.Get<V>(key);
        }

        public IEnumerable<string> GetAllKey<V>()
        {
            //性能注意: 只查sqlsugar用到的key 
            return _service.SearchCacheRegex("SqlSugarDataCache.*");
        }

        public V GetOrCreate<V>(string cacheKey, Func<V> create, int cacheDurationInSeconds = int.MaxValue)
        {
          
            if (this.ContainsKey<V>(cacheKey))
            {
                var result=this.Get<V>(cacheKey);
                if(result==null)
                {
                   return create();
                }
                else
                {
                   return result;
                }
            }
            else
            {
                var result = create();
                this.Add(cacheKey, result, cacheDurationInSeconds);
                return result;
            }
        }

        public void Remove<V>(string key)
        {
            _service.Remove(key);
        }
    }
 //这个类直接复制就行了


6、纯手动使用2缓存

直接用缓存的原生方法

 if (db.DataCache.Get<Order>("key_order") == null)
 {
        var list=db.Queryable<Order>().ToList();
        db.DataCache.Add("key_order",list);
         return list;
  }
  else
  {
         return db.DataCache.Get<Order>("key_order");
  }



共享你们的二级缓存实现类:

1、方便其它人用到

2、方便自已下次用到

共享地址: http://www.donet5.com/Ask/9/11064

关闭
果糖网