关于sqlsugar二级缓存

二级缓存

1、优点

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

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

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

2、原理

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

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

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

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

3、使用

3.1 实现接口 ICacheService
代码:接口实现
 /// <summary>
    /// SqlSugar二级缓存(必须是内存缓存)
    /// </summary>
    public class SqlSugarCache : ICacheService
    {
        private static readonly ICache _cache = Cache.Default;

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

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

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

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

        public IEnumerable<string> GetAllKey<V>()
        {
            return _cache.Keys;
        }

        public V GetOrCreate<V>(string cacheKey, Func<V> create, int cacheDurationInSeconds = int.MaxValue)
        {
            if (!_cache.TryGetValue<V>(cacheKey, out V value))
            {
                value = create();
                _cache.Set(cacheKey, value, cacheDurationInSeconds);
            }
            return value;
        }

        public void Remove<V>(string key)
        {
            _cache.Remove(key);
        }
    }
3.2 创建使用二级缓存,配合租户数据过滤使用
实现

//二级缓存 : SqlSugar二级缓存(必须是内存缓存)
db.CurrentConnectionConfig.ConfigureExternalServices = new ConfigureExternalServices()
{
    //AppSettingsConstVars.RedisUseCache
    //判断是否开启redis设置二级缓存方式
    //DataInfoCacheService = AppSettingsConstVars.RedisUseCache ? (ICacheService)new SqlSugarRedisCache000() : new SqlSugarMemoryCache()
   DataInfoCacheService  = new SqlSugarCache(),
};
//... ... ...
#region 实体配置过滤器
        /// <summary>
        /// 配置租户过滤器
        /// </summary>
        private static void SetTenantEntityFilter(SqlSugarClient db)
        {
            //炒鸡管理员工 直接略过
            var isSuperAdmin = App.User?.Claims?.Where(p => p.Type == ClaimTypes.Role)?.Any(p => p.Value == "superadmin") ?? false ;
            if (isSuperAdmin) return;
           

            var tenantId = App.User?.FindFirst(GlobalConstVars.TenantId)?.Value;
            if (string.IsNullOrWhiteSpace(tenantId)) return;

            // 配置租户缓存
            var cacheKey = $"db:{211314}:TenantId:{tenantId}";
            var tableFilterItemList = db.DataCache.Get<List<TableFilterItem<object>>>(cacheKey);//sqlsugar 二级缓存
            if (tableFilterItemList == null)
            {
                // 获取租户实体数据表
                var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
                    && (u.BaseType == typeof(EntityTenantNew) || u.BaseType == typeof(EntityTenantId)));
                if (!entityTypes.Any()) return;

                var tableFilterItems = new List<TableFilterItem<object>>();
                foreach (var entityType in entityTypes)
                {
                   
                    var lambda = DynamicExpressionParser.ParseLambda(new[] {
                    Expression.Parameter(entityType, "u") }, typeof(bool), $"{nameof(EntityTenantNew.tenantId)} == @0", long.Parse(tenantId));
                    var tableFilterItem = new TableFilterItem<object>(entityType, lambda);
                    tableFilterItems.Add(tableFilterItem);
                    db.QueryFilter.Add(tableFilterItem);
                }
                db.DataCache.Add(cacheKey, tableFilterItems);
            }
            else
            {
                tableFilterItemList.ForEach(u =>
                {
                    db.QueryFilter.Add(u);
                });
            }
        }
        #endregion

posted @ 2023-02-08 17:06  弗里德里希恩格hao  阅读(675)  评论(0)    收藏  举报