1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Web; 7 using ServiceStack.Redis; 8 using System.Data; 9 10 namespace Utils 11 { 12 public static class HttpCache<T> 13 { 14 #region Redis 15 //redis IP地址 16 private static string RedisIP = System.Configuration.ConfigurationSettings.AppSettings["RedisIP"]; 17 //redis密码(不填表示没有密码) 18 private static string RedisPassword = System.Configuration.ConfigurationSettings.AppSettings["RedisPassword"]; 19 //redis端口(不填默认6379) 20 private static int RedisPort = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["RedisPort"]); 21 //redis库索引号(整数,默认有5个库,从0开始,不填表示0) 22 private static int DbIndex = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["RedisDbIndex"]); 23 //redis 是否使用缓存开关 24 private static int isOpenCache = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["IsOpenRedis"]); 25 26 private static PooledRedisClientManager prcm = CreateManager( 27 new string[] { (RedisPassword.Trim() == string.Empty ? "" : RedisPassword + "@") + RedisIP + ":" + RedisPort + " " }, 28 new string[] { (RedisPassword.Trim() == string.Empty ? "" : RedisPassword + "@") + RedisIP + ":" + RedisPort + " " }); 29 private static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts) 30 { 31 // 支持读写分离,均衡负载 32 RedisClientManagerConfig clientConfig = new RedisClientManagerConfig(); 33 34 clientConfig.MaxWritePoolSize = 10000; 35 clientConfig.MaxReadPoolSize = 10000; 36 clientConfig.AutoStart = true; 37 clientConfig.DefaultDb = DbIndex; 38 PooledRedisClientManager clientManager = new PooledRedisClientManager(readWriteHosts, readOnlyHosts, clientConfig); 39 return clientManager; 40 } 41 42 /// <summary> 43 /// 是否使用缓存开关 44 /// </summary> 45 private static bool IsOpenCache 46 { 47 get 48 { 49 if (isOpenCache != 1) return false; 50 return true; 51 } 52 } 53 54 /// <summary> 55 /// 加入缓存 56 /// </summary> 57 /// <typeparam name="T">对象类型</typeparam> 58 /// <param name="key">Key(键值命名规范:RK_字段名_表名_条件字段1_值_条件字段n_值......,键值全部小写,表名不加dbo前缀)</param> 59 /// <param name="value">对象</param> 60 /// <param name="Timer">缓存时间(除了XianZhiAccounts的过期时间为一小时,其余的过期时间都为两天)</param> 61 /// <returns>是否缓存成功</returns> 62 /// 对于datatable 的缓存 需要特殊处理 63 public static bool SaveCaChe(string key, T value) 64 { 65 bool result = false; 66 try 67 { 68 if (IsOpenCache) 69 { 70 if (!(value is DataTable) && !(value is DataSet) && !(value is DataRow)) 71 { 72 using (IRedisClient Redis = prcm.GetClient()) 73 { 74 result = Redis.Set<T>(key, value, DateTime.Now.AddHours(24)); 75 } 76 } 77 else 78 { 79 using (IRedisClient Redis = prcm.GetClient()) 80 { 81 result = Redis.Set<byte[]>(key, SetBytesFormT(value), DateTime.Now.AddHours(24)); 82 } 83 } 84 } 85 } 86 catch { } 87 return result; 88 } 89 public static bool SaveCaChe(string key, T value, int Timer) 90 { 91 bool result = false; 92 try 93 { 94 if (IsOpenCache) 95 { 96 if (!(value is DataTable) && !(value is DataSet) && !(value is DataRow)) 97 { 98 using (IRedisClient Redis = prcm.GetClient()) 99 { 100 result = Redis.Set<T>(key, value, TimeSpan.FromMinutes(Timer)); 101 } 102 } 103 else 104 { 105 using (IRedisClient Redis = prcm.GetClient()) 106 { 107 result = Redis.Set<byte[]>(key, SetBytesFormT(value), DateTime.Now.AddHours(24)); 108 } 109 } 110 } 111 } 112 catch { } 113 return result; 114 } 115 public static bool SaveBaseCaChe(string key, T value) 116 { 117 bool result = false; 118 try 119 { 120 if (IsOpenCache) 121 { 122 if (!(value is DataTable) && !(value is DataSet) && !(value is DataRow)) 123 { 124 using (IRedisClient Redis = prcm.GetClient()) 125 { 126 result = Redis.Set<T>(key, value, DateTime.Now.AddHours(24)); 127 } 128 } 129 else 130 { 131 using (IRedisClient Redis = prcm.GetClient()) 132 { 133 result = Redis.Set<byte[]>(key, SetBytesFormT(value), DateTime.Now.AddHours(24)); 134 } 135 } 136 } 137 } 138 catch { } 139 return result; 140 } 141 public static bool SaveBaseCaChe(string key, T value, int Timer) 142 { 143 bool result = false; 144 try 145 { 146 if (IsOpenCache) 147 { 148 if (!(value is DataTable) && !(value is DataSet) && !(value is DataRow)) 149 { 150 using (IRedisClient Redis = prcm.GetClient()) 151 { 152 result = Redis.Set<T>(key, value, TimeSpan.FromMinutes(Timer)); 153 } 154 } 155 else 156 { 157 using (IRedisClient Redis = prcm.GetClient()) 158 { 159 result = Redis.Set<byte[]>(key, SetBytesFormT(value), TimeSpan.FromMinutes(Timer)); 160 } 161 } 162 } 163 } 164 catch { } 165 return result; 166 } 167 168 /// <summary> 169 /// 获取缓存内容 170 /// </summary> 171 /// <param name="key">Key</param> 172 /// <returns></returns> 173 public static T GetCaChe(string key) 174 { 175 try 176 { 177 if (!IsOpenCache) return default(T); 178 using (IRedisClient Redis = prcm.GetClient()) 179 { 180 return Redis.Get<T>(key); 181 } 182 } 183 catch 184 { 185 string str = string.Empty; 186 return default(T); 187 } 188 } 189 public static T GetBaseCaChe(string key) 190 { 191 try 192 { 193 if (!IsOpenCache) return default(T); 194 using (IRedisClient Redis = prcm.GetClient()) 195 { 196 return Redis.Get<T>(key); 197 } 198 } 199 catch 200 { 201 string str = string.Empty; 202 return default(T); 203 } 204 } 205 /// <summary> 206 /// 对于datatable 的缓存 需要特殊处理 207 /// </summary> 208 /// <typeparam name="T"></typeparam> 209 /// <param name="key"></param> 210 /// <returns></returns> 211 public static T GetBaseCaChe<T>(string key) where T : class 212 { 213 try 214 { 215 if (!IsOpenCache) return default(T); 216 if (!(typeof(T).ToString() == "System.Data.DataTable") 217 && !(typeof(T).ToString() == "System.Data.DataSet") 218 && !(typeof(T).ToString() == "System.Data.DataRow")) 219 { 220 using (IRedisClient Redis = prcm.GetClient()) 221 { 222 return Redis.Get<T>(key); 223 } 224 } 225 else 226 { 227 using (IRedisClient Redis = prcm.GetClient()) 228 { 229 byte[] buffer = Redis.Get<byte[]>(key); 230 return GetObjFromBytes(buffer) as T; 231 } 232 } 233 } 234 catch 235 { 236 string str = string.Empty; 237 return default(T); 238 } 239 } 240 241 /// <summary> 242 /// 删除缓存 243 /// </summary> 244 /// <param name="key">Key</param> 245 /// <returns></returns> 246 public static bool DeleteCache(string key) 247 { 248 try 249 { 250 if (!IsOpenCache) return false; 251 using (IRedisClient Redis = prcm.GetClient()) 252 { 253 return Redis.Remove(key); 254 } 255 } 256 catch { return false; } 257 } 258 259 /// <summary> 260 /// 批量删除缓存 261 /// </summary> 262 /// <param name="keys">Key</param> 263 /// <returns></returns> 264 public static void DeleteCache(List<string> keys) 265 { 266 try 267 { 268 if (!IsOpenCache) return; 269 using (IRedisClient Redis = prcm.GetClient()) 270 { 271 Redis.RemoveAll(keys); 272 } 273 } 274 catch { return; } 275 } 276 277 /// <summary> 278 /// 清空缓存 279 /// </summary> 280 public static void ClearCache() 281 { 282 try 283 { 284 if (!IsOpenCache) return; 285 using (IRedisClient Redis = prcm.GetClient()) 286 { 287 Redis.FlushAll(); 288 } 289 } 290 catch { return; } 291 } 292 /// <summary> 293 /// 是否包含KEY缓存 294 /// </summary> 295 /// <param name="key"></param> 296 /// <returns></returns> 297 public static bool IsContain(string key) 298 { 299 try 300 { 301 if (!IsOpenCache) return false; 302 using (IRedisClient Redis = prcm.GetClient()) 303 { 304 return Redis.ContainsKey(key); 305 } 306 } 307 catch { return false; } 308 } 309 310 public static byte[] SetBytesFormT(T t) 311 { 312 System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();//定义BinaryFormatter以序列化DataSet对象 313 System.IO.MemoryStream ms = new System.IO.MemoryStream();//创建内存流对象 314 formatter.Serialize(ms, t);//把DataSet对象序列化到内存流 315 byte[] buffer = ms.ToArray();//把内存流对象写入字节数组 316 ms.Close();//关闭内存流对象 317 ms.Dispose();//释放资源 318 return buffer; 319 } 320 321 private static object GetObjFromBytes(byte[] buffer) 322 { 323 using (System.IO.MemoryStream stream = new System.IO.MemoryStream(buffer)) 324 { 325 stream.Position = 0; 326 System.Runtime.Serialization.IFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 327 Object reobj = bf.Deserialize(stream); 328 return reobj; 329 } 330 } 331 #endregion 332 } 333 }
公司统一走redis缓存,也将之前的memcache迁移到redis
碰到问题是redis的dataset缓存。
memcache底层封装了dataset的序列化。
而redis引的DLL包,未支持。所以封装一个类,提供dataset的set,get功能。
dataset以转为byte[]保存,读取byte[] 转为dataset