StackExchange.Redis 之 hash 類型示例

StackExchange.Redis 的組件封裝示例網上有不少,自行百度搜索便可。redis

這裏只演示如何使用Hash類型操做數據:數據庫

1             // 在 hash 中存入或修改一個值  並設置order_hashkey有效期1分鐘,過時自動刪除;null爲不過時
2             stopwatch.Start();
3             var isok = RedisCacheHelper.Instance.HashSet("order_hashkey", "order_hashfield", "10", TimeSpan.FromMinutes(1));
4             stopwatch.Stop();
5             Console.WriteLine("在hash中存入一個值消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());  

1             //判斷該字段是否存在 hash 中
2             var isexists = RedisCacheHelper.Instance.HashExists("order_hashkey", "order_hashfield");
3             Console.WriteLine("判斷該字段是否存在hash中:" + isexists);  //返回 True 或 False

             //從hash中移除指定字段
             var isdel = RedisCacheHelper.Instance.HashDelete("order_hashkey", "order_hashfield");
             Console.WriteLine("從hash中移除指定字段:" + isdel);  //返回 True 或 False
            //從hash中遞增  默認按1遞增
            var getincre = RedisCacheHelper.Instance.HashIncrement("order_hashkey", "order_hashfield");
            Console.WriteLine("從hash中遞增:" + getincre);  //返遞增後的值 11

            //從hash中遞減  默認按1遞減
            var getdecre = RedisCacheHelper.Instance.HashDecrement("order_hashkey", "order_hashfield");
            Console.WriteLine("從hash中遞減:" + getdecre);  //返遞減後的值  10

            //保存一個字符串類型集合
            string[] strarray = { "1", "2", "3", "4", "5" };
            RedisCacheHelper.Instance.HashSetList("orderlist_hashkey", strarray, m => { return "hashfield_" + m.ToString(); }, new TimeSpan(0, 0, 50));

            //從數據庫獲取10條數據
            stopwatch.Start();
            var getlist = TestRedis.GetOrderFormAll(10);
            stopwatch.Stop();
            Console.WriteLine("從數據庫獲取10條數據消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());

            //保存多個對象集合 非序列化
            stopwatch.Start();
            RedisCacheHelper.Instance.HashSetObjectList("objlist_hashkey", getlist, r => { return r.ordercode.ToString(); }, 1);
            stopwatch.Stop();
            Console.WriteLine("將10條數據存入HashRedis 消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());

 

            //保存或修改一個hash對象(序列化) 對key設置過時時間有時候起做用,有時候不起做用
            stopwatch.Start();
            RedisCacheHelper.Instance.HashSet<OrderForm>("orderform_hashkey", "orderform_hashfield", getlist.FirstOrDefault(), new TimeSpan(0, 0, 10), 2);
            stopwatch.Stop();
            Console.WriteLine("保存或修改一個hash對象(序列化)消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());


            //保存Hash對象集合 序列化   對key設置過時時間能夠起做用
            stopwatch.Start();
            RedisCacheHelper.Instance.HashSet<OrderForm>("orderformlist_hashkey", getlist, m=> { return m.ordercode.ToString(); }, new TimeSpan(0, 0, 30), 3);
            stopwatch.Stop();
            Console.WriteLine("保存Hash對象集合(序列化)消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());

 

            //從Hash Redis獲取某一條訂單信息  反序列化
            stopwatch.Start();
            var getorderinfo = RedisCacheHelper.Instance.HashGet<OrderForm>("orderform_hashkey", "orderform_hashfield", 2);
            stopwatch.Stop();
            Console.WriteLine("從Hash Redis獲取某一條訂單信息消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
            Console.WriteLine(getorderinfo.ordercode);
            Console.WriteLine(getorderinfo.Area);
            Console.WriteLine(getorderinfo.City);
            Console.WriteLine(getorderinfo.Province);
            Console.WriteLine(getorderinfo.PostTime);

            //根據hashkey 獲取全部的值  反序列化
            stopwatch.Start();
            var getorderlist = RedisCacheHelper.Instance.HashGetAll<OrderForm>("orderformlist_hashkey", 3);
            stopwatch.Stop();
            Console.WriteLine("根據hashkey 獲取全部的值消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
            foreach (var item in getorderlist)
            {
                Console.WriteLine("獲取反序列化獲得的ordercode: " + item.ordercode);
            }

            //根據hashkey獲取單個字段hashField的值
            stopwatch.Start();
            var getvalue = RedisCacheHelper.Instance.HashGet("objlist_hashkey1", "City", 1);
            stopwatch.Stop();
            Console.WriteLine("獲取單個字段hashField的值消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
            Console.WriteLine("獲取City: " + getvalue);

            Console.WriteLine("------------------");
            Console.WriteLine();

            //獲取多個字段hashField的值
            List<RedisValue> fieldlist = new List<RedisValue>() { "ordercode", "Province", "City", "Area" };
            stopwatch.Start();
            var getlist = RedisCacheHelper.Instance.HashGet("objlist_hashkey1", fieldlist.ToArray(), 1);
            stopwatch.Stop();
            Console.WriteLine("獲取多個字段hashField的值消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
            foreach (var item in getlist)
            {
                Console.WriteLine("獲取到的值: " + item);
            }

            //根據hashkey返回全部的HashFiled
            stopwatch.Start();
            var getkeylist = RedisCacheHelper.Instance.HashKeys("objlist_hashkey1", 1);
            stopwatch.Stop();
            Console.WriteLine("消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
            foreach (var item in getkeylist)
            {
                Console.WriteLine("獲取到的HashFiled: " + item);
            }


            //根據hashkey返回全部HashFiled值
            stopwatch.Start();
            var getvaluelist = RedisCacheHelper.Instance.HashValues("objlist_hashkey1", 1);
            stopwatch.Stop();
            Console.WriteLine("消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());
            foreach (var item in getvaluelist)
            {
                Console.WriteLine("獲取到的HashFiled值: " + item);
            }

            //模擬併發場景 使用HashDecrement遞減功能  使用分佈式鎖,可是線程線程排隊處理,有可能照成Redis超時
該示例會照成1個用戶搶多個
stopwatch.Start(); List<Task> taskList = new List<Task>(); for (int i = 1; i <= 100; i++) //模擬多個用戶同時請求 { var task = Task.Run(() => { try { //*************************開始**************** RedisValue token = Environment.MachineName; while (true) { if (RedisCacheHelper.Instance.LockAndDo("lock_key", token, () => { //在這裏處理併發邏輯 //先獲取庫存數 var getvalues = (int)RedisCacheHelper.Instance.HashGet("order_hashkey", "order_hashfield"); if (getvalues > 0) { //先自減,獲取自減後的值 int order_Num = (int)RedisCacheHelper.Instance.HashDecrement("order_hashkey", "order_hashfield", null); if (order_Num >= 0) { //下面執行訂單邏輯(這裏不考慮業務出錯的狀況) Console.WriteLine("我搶到了,還剩餘數量:" + order_Num); } else { Console.WriteLine("A商品已經被搶光了"); } return true; } else { Console.WriteLine("B商品已經被搶光了"); return true; } }, new TimeSpan(0, 0, 10))) { break; } } } catch (Exception ex) { Console.WriteLine(ex.Message); throw; } }); taskList.Add(task); } Task.WaitAll(taskList.ToArray()); stopwatch.Stop(); Console.WriteLine("模擬併發場景消耗時間:" + stopwatch.ElapsedMilliseconds.ToString());

搶購前庫存30個json

 

 搶購後庫存0併發

 

這裏附上RedisHelp分佈式

        /// <summary>
        /// 判斷該字段是否存在 hash 中
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public bool HashExists(string redisKey, string hashField, int db = -1)
        {
            try
            {
                _db = GetDatabase(db);
                return _db.HashExists(redisKey, hashField);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 從 hash 中移除指定字段
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public bool HashDelete(string redisKey, string hashField, int db = -1)
        {
            try
            {
                _db = GetDatabase(db);
                return _db.HashDelete(redisKey, hashField);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 從 hash 中移除多個指定字段
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public long HashDelete(string redisKey, IEnumerable<RedisValue> hashField, int db = -1)
        {
            try
            {
                _db = GetDatabase(db);
                return _db.HashDelete(redisKey, hashField.ToArray());
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 遞增  默認按1遞增  可用於計數
        /// </summary>
        /// <param name="key"></param>
        /// <param name="span"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public long HashIncrement(string redisKey, string hashField, TimeSpan? span = null, int db = -1)
        {
            try
            {
                _db = GetDatabase(db);
                var result = _db.HashIncrement(redisKey, hashField);
                //設置過時時間
                if (span != null)
                {
                    this.KeyExpire(redisKey, span);
                }
                return result;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 遞減  默認按1遞減   可用於搶購類的案例
        /// </summary>
        /// <param name="key"></param>
        /// <param name="span"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public long HashDecrement(string redisKey, string hashField, TimeSpan? span = null, int db = -1)
        {
            try
            {
                _db = GetDatabase(db);
                var result = _db.HashDecrement(redisKey, hashField);
                //設置過時時間
                if (span != null)
                {
                    this.KeyExpire(redisKey, span);
                }
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }


        /// <summary>
        /// 在 hash 中保存或修改一個值   字符類型
        /// set or update the HashValue for string key 
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <param name="value"></param>
        /// <param name="span">過時時間,可空</param>
        /// <returns></returns>
        public bool HashSet(string redisKey, string hashField, string value, TimeSpan? span = null, int db = -1)
        {
            try
            {
                _db = GetDatabase(db);
                if (span != null)
                {
                    //設置過時時間
                    this.KeyExpire(redisKey, span);
                }
                return _db.HashSet(redisKey, hashField, value);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 保存一個字符串類型集合  
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey">Redis Key</param>
        /// <param name="list">數據集合</param>
        /// <param name="getFiledKey">字段key</param>
        public void HashSetList(string redisKey, IEnumerable<string> list, Func<string, string> getFiledKey, TimeSpan? span = null, int db = -1)
        {
            try
            {
                _db = GetDatabase(db);
                List<HashEntry> listHashEntry = new List<HashEntry>();
                foreach (var item in list)
                {
                    listHashEntry.Add(new HashEntry(getFiledKey(item), item));
                }
                _db.HashSet(redisKey, listHashEntry.ToArray());

                if (span != null)
                {
                    //設置過時時間
                    this.KeyExpire(redisKey, span);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }


        /// <summary>
        /// 保存多個對象集合  非序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tableName">表名前綴</param>
        /// <param name="list">數據集合</param>
        /// <param name="getModelId">字段key</param>
        public void HashSetObjectList<T>(string tableName, IEnumerable<T> list, Func<T, string> getModelId, int db = -1) where T : class
        {
            try
            {
                _db = GetDatabase(db);
                foreach (var item in list)
                {
                    List<HashEntry> listHashEntry = new List<HashEntry>();
                    Type t = item.GetType();//得到該類的Type
                    foreach (PropertyInfo pi in t.GetProperties())
                    {
                        string name = pi.Name; //得到屬性的名字,後面就能夠根據名字判斷來進行些本身想要的操做
                        var value = pi.GetValue(item, null);  //用pi.GetValue得到值
                        listHashEntry.Add(new HashEntry(name, value.ToString()));
                    }
                    _db.HashSet(tableName + getModelId(item), listHashEntry.ToArray());
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }


        /// <summary>
        /// 保存或修改一個hash對象(序列化)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool HashSet<T>(string redisKey, string hashField, T value, TimeSpan? span = null, int db = -1) where T : class
        {
            try
            {
                _db = GetDatabase(db);
                var json = JsonConvert.SerializeObject(value);
                if (span != null)
                {
                    //設置過時時間
                    this.KeyExpire(redisKey, span);
                }
                return _db.HashSet(redisKey, hashField, json);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 保存Hash對象集合 序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey">Redis Key</param>
        /// <param name="list">數據集合</param>
        /// <param name="getModelId"></param>
        public void HashSet<T>(string redisKey, IEnumerable<T> list, Func<T, string> getModelId, TimeSpan? span = null, int db = -1) where T : class
        {
            try
            {
                _db = GetDatabase(db);
                List<HashEntry> listHashEntry = new List<HashEntry>();
                foreach (var item in list)
                {
                    string json = JsonConvert.SerializeObject(item);
                    listHashEntry.Add(new HashEntry(getModelId(item), json));
                }
                _db.HashSet(redisKey, listHashEntry.ToArray());

                if (span != null)
                {
                    //設置過時時間
                    this.KeyExpire(redisKey, span);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        /// <summary>
        /// 從 hash 中獲取對象(反序列化)
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public T HashGet<T>(string redisKey, string hashField, int db = -1) where T : class
        {
            try
            {
                _db = GetDatabase(db);
                return JsonConvert.DeserializeObject<T>(_db.HashGet(redisKey, hashField));
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        ///  根據hashkey獲取全部的值  序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public List<T> HashGetAll<T>(string redisKey, int db = -1) where T : class
        {
            List<T> result = new List<T>();
            try
            {
                _db = GetDatabase(db);
                HashEntry[] arr = _db.HashGetAll(redisKey);
                foreach (var item in arr)
                {
                    if (!item.Value.IsNullOrEmpty)
                    {
                        var t = JsonConvert.DeserializeObject<T>(item.Value);
                        if (t != null)
                        {
                            result.Add(t);
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return result;
        }


        /// <summary>
        ///  根據hashkey獲取全部的值  非序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public IEnumerable<Dictionary<RedisValue, RedisValue>> HashGetAll(IEnumerable<string> redisKey, int db = -1)
        {
            List<Dictionary<RedisValue, RedisValue>> diclist = new List<Dictionary<RedisValue, RedisValue>>();
            try
            {
                _db = GetDatabase(db);
                foreach (var item in redisKey)
                {
                    HashEntry[] arr = _db.HashGetAll(item);
                    foreach (var he in arr)
                    {
                        Dictionary<RedisValue, RedisValue> dic = new Dictionary<RedisValue, RedisValue>();
                        if (!he.Value.IsNullOrEmpty)
                        {
                            dic.Add(he.Name, he.Value);
                        }
                        diclist.Add(dic);
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return diclist;
        }


        /// <summary>
        /// 根據hashkey獲取單個字段hashField的值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public RedisValue HashGet(string redisKey, string hashField, int db = -1)
        {
            try
            {
                _db = GetDatabase(db);
                return _db.HashGet(redisKey, hashField);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 根據hashkey獲取多個字段hashField的值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        public RedisValue[] HashGet(string redisKey, RedisValue[] hashField, int db = -1)
        {
            _db = GetDatabase(db);
            return _db.HashGet(redisKey, hashField);
        }

        /// <summary>
        /// 根據hashkey返回全部的HashFiled
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public IEnumerable<RedisValue> HashKeys(string redisKey, int db = -1)
        {
            _db = GetDatabase(db);
            return _db.HashKeys(redisKey);
        }

        /// <summary>
        /// 根據hashkey返回全部HashValue值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        public RedisValue[] HashValues(string redisKey, int db = -1)
        {
            _db = GetDatabase(db);
            return _db.HashValues(redisKey);
        }
View Code
相關文章
相關標籤/搜索