一.redis简介
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
Redis支持数据的备份,即master-slave模式的数据备份。
两种持久化机制:https://www.cnblogs.com/xingzc/p/5988080.html
二.Spring配置redis
配置jedis的jar包:pom.xml:
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.0.1</version> </dependency>
redis.properties(redis配置信息):
redis.hostname=127.0.0.1
redis.port=6379
redis.database=0
redis.pool.maxActive=600
redis.pool.maxIdle=300
redis.pool.maxWait=3000
redis.pool.testOnBorrow=true
加载redis配置信息:
连接池对象操作类(JedisPoolWriper):
1 package com.swpu.o2o.cache; 2 3 import redis.clients.jedis.JedisPool; 4 import redis.clients.jedis.JedisPoolConfig; 5 6 /** 7 * 强指定redis的JedisPool接口构造函数,这样才能在centos成功创建jedispool 8 * 9 * @author xiangze 10 * 11 */ 12 public class JedisPoolWriper { 13 //连接池对象 14 private JedisPool jedisPool; 15 16 public JedisPoolWriper(final JedisPoolConfig poolConfig, final String host, 17 final int port) { 18 try { 19 //通过连接池配置信息,IP,端口构造连接池对象 20 jedisPool = new JedisPool(poolConfig, host, port); 21 } catch (Exception e) { 22 e.printStackTrace(); 23 } 24 } 25 //获取redis连接池对象 26 public JedisPool getJedisPool() { 27 return jedisPool; 28 } 29 //注入redis连接池对象 30 public void setJedisPool(JedisPool jedisPool) { 31 this.jedisPool = jedisPool; 32 } 33 34 }
封装好的redis相关操作(工具类,JedisUtil):
1 package com.swpu.o2o.cache; 2 3 import java.util.List; 4 import java.util.Map; 5 import java.util.Set; 6 7 import redis.clients.jedis.BinaryClient.LIST_POSITION; 8 import redis.clients.jedis.Jedis; 9 import redis.clients.jedis.JedisPool; 10 import redis.clients.jedis.SortingParams; 11 import redis.clients.util.SafeEncoder; 12 13 public class JedisUtil { 14 /** 15 * 缓存生存时间 16 */ 17 private final int expire = 60000; 18 /** 操作Key的方法 */ 19 public Keys KEYS; 20 /** 对存储结构为String类型的操作 */ 21 public Strings STRINGS; 22 /** 对存储结构为List类型的操作 */ 23 public Lists LISTS; 24 /** 对存储结构为Set类型的操作 */ 25 public Sets SETS; 26 /** 对存储结构为HashMap类型的操作 */ 27 public Hash HASH; 28 29 private JedisPool jedisPool; 30 31 public JedisPool getJedisPool() { 32 return jedisPool; 33 } 34 35 public void setJedisPool(JedisPoolWriper jedisPoolWriper) { 36 this.jedisPool = jedisPoolWriper.getJedisPool(); 37 } 38 39 public JedisPool getPool() { 40 return jedisPool; 41 } 42 43 /** 44 * 从jedis连接池中获取获取jedis对象 45 * 46 * @return 47 */ 48 public Jedis getJedis() { 49 return jedisPool.getResource(); 50 } 51 52 /** 53 * 设置过期时间 54 * 55 * @author ruan 2013-4-11 56 * @param key 57 * @param seconds 58 */ 59 public void expire(String key, int seconds) { 60 if (seconds <= 0) { 61 return; 62 } 63 Jedis jedis = getJedis(); 64 jedis.expire(key, seconds); 65 jedis.close(); 66 } 67 68 /** 69 * 设置默认过期时间 70 * 71 * @author ruan 2013-4-11 72 * @param key 73 */ 74 public void expire(String key) { 75 expire(key, expire); 76 } 77 78 // *******************************************Keys*******************************************// 79 public class Keys { 80 81 /** 82 * 清空所有key 83 */ 84 public String flushAll() { 85 Jedis jedis = getJedis(); 86 String stata = jedis.flushAll(); 87 jedis.close(); 88 return stata; 89 } 90 91 /** 92 * 更改key 93 * 94 * @param String 95 * oldkey 96 * @param String 97 * newkey 98 * @return 状态码 99 * */ 100 public String rename(String oldkey, String newkey) { 101 return rename(SafeEncoder.encode(oldkey), 102 SafeEncoder.encode(newkey)); 103 } 104 105 /** 106 * 更改key,仅当新key不存在时才执行 107 * 108 * @param String 109 * oldkey 110 * @param String 111 * newkey 112 * @return 状态码 113 * */ 114 public long renamenx(String oldkey, String newkey) { 115 Jedis jedis = getJedis(); 116 long status = jedis.renamenx(oldkey, newkey); 117 jedis.close(); 118 return status; 119 } 120 121 /** 122 * 更改key 123 * 124 * @param String 125 * oldkey 126 * @param String 127 * newkey 128 * @return 状态码 129 * */ 130 public String rename(byte[] oldkey, byte[] newkey) { 131 Jedis jedis = getJedis(); 132 String status = jedis.rename(oldkey, newkey); 133 jedis.close(); 134 return status; 135 } 136 137 /** 138 * 设置key的过期时间,以秒为单位 139 * 140 * @param String 141 * key 142 * @param 时间 143 * ,已秒为单位 144 * @return 影响的记录数 145 * */ 146 public long expired(String key, int seconds) { 147 Jedis jedis = getJedis(); 148 long count = jedis.expire(key, seconds); 149 jedis.close(); 150 return count; 151 } 152 153 /** 154 * 设置key的过期时间,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00,格里高利历)的偏移量。 155 * 156 * @param String 157 * key 158 * @param 时间 159 * ,已秒为单位 160 * @return 影响的记录数 161 * */ 162 public long expireAt(String key, long timestamp) { 163 Jedis jedis = getJedis(); 164 long count = jedis.expireAt(key, timestamp); 165 jedis.close(); 166 return count; 167 } 168 169 /** 170 * 查询key的过期时间 171 * 172 * @param String 173 * key 174 * @return 以秒为单位的时间表示 175 * */ 176 public long ttl(String key) { 177 // ShardedJedis sjedis = getShardedJedis(); 178 Jedis sjedis = getJedis(); 179 long len = sjedis.ttl(key); 180 sjedis.close(); 181 return len; 182 } 183 184 /** 185 * 取消对key过期时间的设置 186 * 187 * @param key 188 * @return 影响的记录数 189 * */ 190 public long persist(String key) { 191 Jedis jedis = getJedis(); 192 long count = jedis.persist(key); 193 jedis.close(); 194 return count; 195 } 196 197 /** 198 * 删除keys对应的记录,可以是多个key 199 * 200 * @param String 201 * ... keys 202 * @return 删除的记录数 203 * */ 204 public long del(String... keys) { 205 Jedis jedis = getJedis(); 206 long count = jedis.del(keys); 207 jedis.close(); 208 return count; 209 } 210 211 /** 212 * 删除keys对应的记录,可以是多个key 213 * 214 * @param String 215 * ... keys 216 * @return 删除的记录数 217 * */ 218 public long del(byte[]... keys) { 219 Jedis jedis = getJedis(); 220 long count = jedis.del(keys); 221 jedis.close(); 222 return count; 223 } 224 225 /** 226 * 判断key是否存在 227 * 228 * @param String 229 * key 230 * @return boolean 231 * */ 232 public boolean exists(String key) { 233 // ShardedJedis sjedis = getShardedJedis(); 234 Jedis sjedis = getJedis(); 235 boolean exis = sjedis.exists(key); 236 sjedis.close(); 237 return exis; 238 } 239 240 /** 241 * 对List,Set,SortSet进行排序,如果集合数据较大应避免使用这个方法 242 * 243 * @param String 244 * key 245 * @return List<String> 集合的全部记录 246 * **/ 247 public List<String> sort(String key) { 248 // ShardedJedis sjedis = getShardedJedis(); 249 Jedis sjedis = getJedis(); 250 List<String> list = sjedis.sort(key); 251 sjedis.close(); 252 return list; 253 } 254 255 /** 256 * 对List,Set,SortSet进行排序或limit 257 * 258 * @param String 259 * key 260 * @param SortingParams 261 * parame 定义排序类型或limit的起止位置. 262 * @return List<String> 全部或部分记录 263 * **/ 264 public List<String> sort(String key, SortingParams parame) { 265 // ShardedJedis sjedis = getShardedJedis(); 266 Jedis sjedis = getJedis(); 267 List<String> list = sjedis.sort(key, parame); 268 sjedis.close(); 269 return list; 270 } 271 272 /** 273 * 返回指定key存储的类型 274 * 275 * @param String 276 * key 277 * @return String string|list|set|zset|hash 278 * **/ 279 public String type(String key) { 280 // ShardedJedis sjedis = getShardedJedis(); 281 Jedis sjedis = getJedis(); 282 String type = sjedis.type(key); 283 sjedis.close(); 284 return type; 285 } 286 287 /** 288 * 查找所有匹配给定的模式的键 289 * 290 * @param String 291 * key的表达式,*表示多个,?表示一个 292 * */ 293 public Set<String> keys(String pattern) { 294 Jedis jedis = getJedis(); 295 Set<String> set = jedis.keys(pattern); 296 jedis.close(); 297 return set; 298 } 299 } 300 301 // *******************************************Sets*******************************************// 302 public class Sets { 303 304 /** 305 * 向Set添加一条记录,如果member已存在返回0,否则返回1 306 * 307 * @param String 308 * key 309 * @param String 310 * member 311 * @return 操作码,0或1 312 * */ 313 public long sadd(String key, String member) { 314 Jedis jedis = getJedis(); 315 long s = jedis.sadd(key, member); 316 jedis.close(); 317 return s; 318 } 319 320 public long sadd(byte[] key, byte[] member) { 321 Jedis jedis = getJedis(); 322 long s = jedis.sadd(key, member); 323 jedis.close(); 324 return s; 325 } 326 327 /** 328 * 获取给定key中元素个数 329 * 330 * @param String 331 * key 332 * @return 元素个数 333 * */ 334 public long scard(String key) { 335 // ShardedJedis sjedis = getShardedJedis(); 336 Jedis sjedis = getJedis(); 337 long len = sjedis.scard(key); 338 sjedis.close(); 339 return len; 340 } 341 342 /** 343 * 返回从第一组和所有的给定集合之间的差异的成员 344 * 345 * @param String 346 * ... keys 347 * @return 差异的成员集合 348 * */ 349 public Set<String> sdiff(String... keys) { 350 Jedis jedis = getJedis(); 351 Set<String> set = jedis.sdiff(keys); 352 jedis.close(); 353 return set; 354 } 355 356 /** 357 * 这个命令等于sdiff,但返回的不是结果集,而是将结果集存储在新的集合中,如果目标已存在,则覆盖。 358 * 359 * @param String 360 * newkey 新结果集的key 361 * @param String 362 * ... keys 比较的集合 363 * @return 新集合中的记录数 364 * **/ 365 public long sdiffstore(String newkey, String... keys) { 366 Jedis jedis = getJedis(); 367 long s = jedis.sdiffstore(newkey, keys); 368 jedis.close(); 369 return s; 370 } 371 372 /** 373 * 返回给定集合交集的成员,如果其中一个集合为不存在或为空,则返回空Set 374 * 375 * @param String 376 * ... keys 377 * @return 交集成员的集合 378 * **/ 379 public Set<String> sinter(String... keys) { 380 Jedis jedis = getJedis(); 381 Set<String> set = jedis.sinter(keys); 382 jedis.close(); 383 return set; 384 } 385 386 /** 387 * 这个命令等于sinter,但返回的不是结果集,而是将结果集存储在新的集合中,如果目标已存在,则覆盖。 388 * 389 * @param String 390 * newkey 新结果集的key 391 * @param String 392 * ... keys 比较的集合 393 * @return 新集合中的记录数 394 * **/ 395 public long sinterstore(String newkey, String... keys) { 396 Jedis jedis = getJedis(); 397 long s = jedis.sinterstore(newkey, keys); 398 jedis.close(); 399 return s; 400 } 401 402 /** 403 * 确定一个给定的值是否存在 404 * 405 * @param String 406 * key 407 * @param String 408 * member 要判断的值 409 * @return 存在返回1,不存在返回0 410 * **/ 411 public boolean sismember(String key, String member) { 412 // ShardedJedis sjedis = getShardedJedis(); 413 Jedis sjedis = getJedis(); 414 boolean s = sjedis.sismember(key, member); 415 sjedis.close(); 416 return s; 417 } 418 419 /** 420 * 返回集合中的所有成员 421 * 422 * @param String 423 * key 424 * @return 成员集合 425 * */ 426 public Set<String> smembers(String key) { 427 // ShardedJedis sjedis = getShardedJedis(); 428 Jedis sjedis = getJedis(); 429 Set<String> set = sjedis.smembers(key); 430 sjedis.close(); 431 return set; 432 } 433 434 public Set<byte[]> smembers(byte[] key) { 435 // ShardedJedis sjedis = getShardedJedis(); 436 Jedis sjedis = getJedis(); 437 Set<byte[]> set = sjedis.smembers(key); 438 sjedis.close(); 439 return set; 440 } 441 442 /** 443 * 将成员从源集合移出放入目标集合 <br/> 444 * 如果源集合不存在或不包哈指定成员,不进行任何操作,返回0<br/> 445 * 否则该成员从源集合上删除,并添加到目标集合,如果目标集合中成员已存在,则只在源集合进行删除 446 * 447 * @param String 448 * srckey 源集合 449 * @param String 450 * dstkey 目标集合 451 * @param String 452 * member 源集合中的成员 453 * @return 状态码,1成功,0失败 454 * */ 455 public long smove(String srckey, String dstkey, String member) { 456 Jedis jedis = getJedis(); 457 long s = jedis.smove(srckey, dstkey, member); 458 jedis.close(); 459 return s; 460 } 461 462 /** 463 * 从集合中删除成员 464 * 465 * @param String 466 * key 467 * @return 被删除的成员 468 * */ 469 public String spop(String key) { 470 Jedis jedis = getJedis(); 471 String s = jedis.spop(key); 472 jedis.close(); 473 return s; 474 } 475 476 /** 477 * 从集合中删除指定成员 478 * 479 * @param String 480 * key 481 * @param String 482 * member 要删除的成员 483 * @return 状态码,成功返回1,成员不存在返回0 484 * */ 485 public long srem(String key, String member) { 486 Jedis jedis = getJedis(); 487 long s = jedis.srem(key, member); 488 jedis.close(); 489 return s; 490 } 491 492 /** 493 * 合并多个集合并返回合并后的结果,合并后的结果集合并不保存<br/> 494 * 495 * @param String 496 * ... keys 497 * @return 合并后的结果集合 498 * @see sunionstore 499 * */ 500 public Set<String> sunion(String... keys) { 501 Jedis jedis = getJedis(); 502 Set<String> set = jedis.sunion(keys); 503 jedis.close(); 504 return set; 505 } 506 507 /** 508 * 合并多个集合并将合并后的结果集保存在指定的新集合中,如果新集合已经存在则覆盖 509 * 510 * @param String 511 * newkey 新集合的key 512 * @param String 513 * ... keys 要合并的集合 514 * **/ 515 public long sunionstore(String newkey, String... keys) { 516 Jedis jedis = getJedis(); 517 long s = jedis.sunionstore(newkey, keys); 518 jedis.close(); 519 return s; 520 } 521 } 522 523 // *******************************************Hash*******************************************// 524 public class Hash { 525 526 /** 527 * 从hash中删除指定的存储 528 * 529 * @param String 530 * key 531 * @param String 532 * fieid 存储的名字 533 * @return 状态码,1成功,0失败 534 * */ 535 public long hdel(String key, String fieid) { 536 Jedis jedis = getJedis(); 537 long s = jedis.hdel(key, fieid); 538 jedis.close(); 539 return s; 540 } 541 542 public long hdel(String key) { 543 Jedis jedis = getJedis(); 544 long s = jedis.del(key); 545 jedis.close(); 546 return s; 547 } 548 549 /** 550 * 测试hash中指定的存储是否存在 551 * 552 * @param String 553 * key 554 * @param String 555 * fieid 存储的名字 556 * @return 1存在,0不存在 557 * */ 558 public boolean hexists(String key, String fieid) { 559 // ShardedJedis sjedis = getShardedJedis(); 560 Jedis sjedis = getJedis(); 561 boolean s = sjedis.hexists(key, fieid); 562 sjedis.close(); 563 return s; 564 } 565 566 /** 567 * 返回hash中指定存储位置的值 568 * 569 * @param String 570 * key 571 * @param String 572 * fieid 存储的名字 573 * @return 存储对应的值 574 * */ 575 public String hget(String key, String fieid) { 576 // ShardedJedis sjedis = getShardedJedis(); 577 Jedis sjedis = getJedis(); 578 String s = sjedis.hget(key, fieid); 579 sjedis.close(); 580 return s; 581 } 582 583 public byte[] hget(byte[] key, byte[] fieid) { 584 // ShardedJedis sjedis = getShardedJedis(); 585 Jedis sjedis = getJedis(); 586 byte[] s = sjedis.hget(key, fieid); 587 sjedis.close(); 588 return s; 589 } 590 591 /** 592 * 以Map的形式返回hash中的存储和值 593 * 594 * @param String 595 * key 596 * @return Map<Strinig,String> 597 * */ 598 public Map<String, String> hgetAll(String key) { 599 // ShardedJedis sjedis = getShardedJedis(); 600 Jedis sjedis = getJedis(); 601 Map<String, String> map = sjedis.hgetAll(key); 602 sjedis.close(); 603 return map; 604 } 605 606 /** 607 * 添加一个对应关系 608 * 609 * @param String 610 * key 611 * @param String 612 * fieid 613 * @param String 614 * value 615 * @return 状态码 1成功,0失败,fieid已存在将更新,也返回0 616 * **/ 617 public long hset(String key, String fieid, String value) { 618 Jedis jedis = getJedis(); 619 long s = jedis.hset(key, fieid, value); 620 jedis.close(); 621 return s; 622 } 623 624 public long hset(String key, String fieid, byte[] value) { 625 Jedis jedis = getJedis(); 626 long s = jedis.hset(key.getBytes(), fieid.getBytes(), value); 627 jedis.close(); 628 return s; 629 } 630 631 /** 632 * 添加对应关系,只有在fieid不存在时才执行 633 * 634 * @param String 635 * key 636 * @param String 637 * fieid 638 * @param String 639 * value 640 * @return 状态码 1成功,0失败fieid已存 641 * **/ 642 public long hsetnx(String key, String fieid, String value) { 643 Jedis jedis = getJedis(); 644 long s = jedis.hsetnx(key, fieid, value); 645 jedis.close(); 646 return s; 647 } 648 649 /** 650 * 获取hash中value的集合 651 * 652 * @param String 653 * key 654 * @return List<String> 655 * */ 656 public List<String> hvals(String key) { 657 // ShardedJedis sjedis = getShardedJedis(); 658 Jedis sjedis = getJedis(); 659 List<String> list = sjedis.hvals(key); 660 sjedis.close(); 661 return list; 662 } 663 664 /** 665 * 在指定的存储位置加上指定的数字,存储位置的值必须可转为数字类型 666 * 667 * @param String 668 * key 669 * @param String 670 * fieid 存储位置 671 * @param String 672 * long value 要增加的值,可以是负数 673 * @return 增加指定数字后,存储位置的值 674 * */ 675 public long hincrby(String key, String fieid, long value) { 676 Jedis jedis = getJedis(); 677 long s = jedis.hincrBy(key, fieid, value); 678 jedis.close(); 679 return s; 680 } 681 682 /** 683 * 返回指定hash中的所有存储名字,类似Map中的keySet方法 684 * 685 * @param String 686 * key 687 * @return Set<String> 存储名称的集合 688 * */ 689 public Set<String> hkeys(String key) { 690 // ShardedJedis sjedis = getShardedJedis(); 691 Jedis sjedis = getJedis(); 692 Set<String> set = sjedis.hkeys(key); 693 sjedis.close(); 694 return set; 695 } 696 697 /** 698 * 获取hash中存储的个数,类似Map中size方法 699 * 700 * @param String 701 * key 702 * @return long 存储的个数 703 * */ 704 public long hlen(String key) { 705 // ShardedJedis sjedis = getShardedJedis(); 706 Jedis sjedis = getJedis(); 707 long len = sjedis.hlen(key); 708 sjedis.close(); 709 return len; 710 } 711 712 /** 713 * 根据多个key,获取对应的value,返回List,如果指定的key不存在,List对应位置为null 714 * 715 * @param String 716 * key 717 * @param String 718 * ... fieids 存储位置 719 * @return List<String> 720 * */ 721 public List<String> hmget(String key, String... fieids) { 722 // ShardedJedis sjedis = getShardedJedis(); 723 Jedis sjedis = getJedis(); 724 List<String> list = sjedis.hmget(key, fieids); 725 sjedis.close(); 726 return list; 727 } 728 729 public List<byte[]> hmget(byte[] key, byte[]... fieids) { 730 // ShardedJedis sjedis = getShardedJedis(); 731 Jedis sjedis = getJedis(); 732 List<byte[]> list = sjedis.hmget(key, fieids); 733 sjedis.close(); 734 return list; 735 } 736 737 /** 738 * 添加对应关系,如果对应关系已存在,则覆盖 739 * 740 * @param Strin 741 * key 742 * @param Map 743 * <String,String> 对应关系 744 * @return 状态,成功返回OK 745 * */ 746 public String hmset(String key, Map<String, String> map) { 747 Jedis jedis = getJedis(); 748 String s = jedis.hmset(key, map); 749 jedis.close(); 750 return s; 751 } 752 753 /** 754 * 添加对应关系,如果对应关系已存在,则覆盖 755 * 756 * @param Strin 757 * key 758 * @param Map 759 * <String,String> 对应关系 760 * @return 状态,成功返回OK 761 * */ 762 public String hmset(byte[] key, Map<byte[], byte[]> map) { 763 Jedis jedis = getJedis(); 764 String s = jedis.hmset(key, map); 765 jedis.close(); 766 return s; 767 } 768 769 } 770 771 // *******************************************Strings*******************************************// 772 public class Strings { 773 /** 774 * 根据key获取记录 775 * 776 * @param String 777 * key 778 * @return 值 779 * */ 780 public String get(String key) { 781 // ShardedJedis sjedis = getShardedJedis(); 782 Jedis sjedis = getJedis(); 783 String value = sjedis.get(key); 784 sjedis.close(); 785 return value; 786 } 787 788 /** 789 * 根据key获取记录 790 * 791 * @param byte[] key 792 * @return 值 793 * */ 794 public byte[] get(byte[] key) { 795 // ShardedJedis sjedis = getShardedJedis(); 796 Jedis sjedis = getJedis(); 797 byte[] value = sjedis.get(key); 798 sjedis.close(); 799 return value; 800 } 801 802 /** 803 * 添加有过期时间的记录 804 * 805 * @param String 806 * key 807 * @param int seconds 过期时间,以秒为单位 808 * @param String 809 * value 810 * @return String 操作状态 811 * */ 812 public String setEx(String key, int seconds, String value) { 813 Jedis jedis = getJedis(); 814 String str = jedis.setex(key, seconds, value); 815 jedis.close(); 816 return str; 817 } 818 819 /** 820 * 添加有过期时间的记录 821 * 822 * @param String 823 * key 824 * @param int seconds 过期时间,以秒为单位 825 * @param String 826 * value 827 * @return String 操作状态 828 * */ 829 public String setEx(byte[] key, int seconds, byte[] value) { 830 Jedis jedis = getJedis(); 831 String str = jedis.setex(key, seconds, value); 832 jedis.close(); 833 return str; 834 } 835 836 /** 837 * 添加一条记录,仅当给定的key不存在时才插入 838 * 839 * @param String 840 * key 841 * @param String 842 * value 843 * @return long 状态码,1插入成功且key不存在,0未插入,key存在 844 * */ 845 public long setnx(String key, String value) { 846 Jedis jedis = getJedis(); 847 long str = jedis.setnx(key, value); 848 jedis.close(); 849 return str; 850 } 851 852 /** 853 * 添加记录,如果记录已存在将覆盖原有的value 854 * 855 * @param String 856 * key 857 * @param String 858 * value 859 * @return 状态码 860 * */ 861 public String set(String key, String value) { 862 return set(SafeEncoder.encode(key), SafeEncoder.encode(value)); 863 } 864 865 /** 866 * 添加记录,如果记录已存在将覆盖原有的value 867 * 868 * @param String 869 * key 870 * @param String 871 * value 872 * @return 状态码 873 * */ 874 public String set(String key, byte[] value) { 875 return set(SafeEncoder.encode(key), value); 876 } 877 878 /** 879 * 添加记录,如果记录已存在将覆盖原有的value 880 * 881 * @param byte[] key 882 * @param byte[] value 883 * @return 状态码 884 * */ 885 public String set(byte[] key, byte[] value) { 886 Jedis jedis = getJedis(); 887 String status = jedis.set(key, value); 888 jedis.close(); 889 return status; 890 } 891 892 /** 893 * 从指定位置开始插入数据,插入的数据会覆盖指定位置以后的数据<br/> 894 * 例:String str1="123456789";<br/> 895 * 对str1操作后setRange(key,4,0000),str1="123400009"; 896 * 897 * @param String 898 * key 899 * @param long offset 900 * @param String 901 * value 902 * @return long value的长度 903 * */ 904 public long setRange(String key, long offset, String value) { 905 Jedis jedis = getJedis(); 906 long len = jedis.setrange(key, offset, value); 907 jedis.close(); 908 return len; 909 } 910 911 /** 912 * 在指定的key中追加value 913 * 914 * @param String 915 * key 916 * @param String 917 * value 918 * @return long 追加后value的长度 919 * **/ 920 public long append(String key, String value) { 921 Jedis jedis = getJedis(); 922 long len = jedis.append(key, value); 923 jedis.close(); 924 return len; 925 } 926 927 /** 928 * 将key对应的value减去指定的值,只有value可以转为数字时该方法才可用 929 * 930 * @param String 931 * key 932 * @param long number 要减去的值 933 * @return long 减指定值后的值 934 * */ 935 public long decrBy(String key, long number) { 936 Jedis jedis = getJedis(); 937 long len = jedis.decrBy(key, number); 938 jedis.close(); 939 return len; 940 } 941 942 /** 943 * <b>可以作为获取唯一id的方法</b><br/> 944 * 将key对应的value加上指定的值,只有value可以转为数字时该方法才可用 945 * 946 * @param String 947 * key 948 * @param long number 要减去的值 949 * @return long 相加后的值 950 * */ 951 public long incrBy(String key, long number) { 952 Jedis jedis = getJedis(); 953 long len = jedis.incrBy(key, number); 954 jedis.close(); 955 return len; 956 } 957 958 /** 959 * 对指定key对应的value进行截取 960 * 961 * @param String 962 * key 963 * @param long startOffset 开始位置(包含) 964 * @param long endOffset 结束位置(包含) 965 * @return String 截取的值 966 * */ 967 public String getrange(String key, long startOffset, long endOffset) { 968 // ShardedJedis sjedis = getShardedJedis(); 969 Jedis sjedis = getJedis(); 970 String value = sjedis.getrange(key, startOffset, endOffset); 971 sjedis.close(); 972 return value; 973 } 974 975 /** 976 * 获取并设置指定key对应的value<br/> 977 * 如果key存在返回之前的value,否则返回null 978 * 979 * @param String 980 * key 981 * @param String 982 * value 983 * @return String 原始value或null 984 * */ 985 public String getSet(String key, String value) { 986 Jedis jedis = getJedis(); 987 String str = jedis.getSet(key, value); 988 jedis.close(); 989 return str; 990 } 991 992 /** 993 * 批量获取记录,如果指定的key不存在返回List的对应位置将是null 994 * 995 * @param String 996 * keys 997 * @return List<String> 值得集合 998 * */ 999 public List<String> mget(String... keys) { 1000 Jedis jedis = getJedis(); 1001 List<String> str = jedis.mget(keys); 1002 jedis.close(); 1003 return str; 1004 } 1005 1006 /** 1007 * 批量存储记录 1008 * 1009 * @param String 1010 * keysvalues 例:keysvalues="key1","value1","key2","value2"; 1011 * @return String 状态码 1012 * */ 1013 public String mset(String... keysvalues) { 1014 Jedis jedis = getJedis(); 1015 String str = jedis.mset(keysvalues); 1016 jedis.close(); 1017 return str; 1018 } 1019 1020 /** 1021 * 获取key对应的值的长度 1022 * 1023 * @param String 1024 * key 1025 * @return value值得长度 1026 * */ 1027 public long strlen(String key) { 1028 Jedis jedis = getJedis(); 1029 long len = jedis.strlen(key); 1030 jedis.close(); 1031 return len; 1032 } 1033 } 1034 1035 // *******************************************Lists*******************************************// 1036 public class Lists { 1037 /** 1038 * List长度 1039 * 1040 * @param String 1041 * key 1042 * @return 长度 1043 * */ 1044 public long llen(String key) { 1045 return llen(SafeEncoder.encode(key)); 1046 } 1047 1048 /** 1049 * List长度 1050 * 1051 * @param byte[] key 1052 * @return 长度 1053 * */ 1054 public long llen(byte[] key) { 1055 // ShardedJedis sjedis = getShardedJedis(); 1056 Jedis sjedis = getJedis(); 1057 long count = sjedis.llen(key); 1058 sjedis.close(); 1059 return count; 1060 } 1061 1062 /** 1063 * 覆盖操作,将覆盖List中指定位置的值 1064 * 1065 * @param byte[] key 1066 * @param int index 位置 1067 * @param byte[] value 值 1068 * @return 状态码 1069 * */ 1070 public String lset(byte[] key, int index, byte[] value) { 1071 Jedis jedis = getJedis(); 1072 String status = jedis.lset(key, index, value); 1073 jedis.close(); 1074 return status; 1075 } 1076 1077 /** 1078 * 覆盖操作,将覆盖List中指定位置的值 1079 * 1080 * @param key 1081 * @param int index 位置 1082 * @param String 1083 * value 值 1084 * @return 状态码 1085 * */ 1086 public String lset(String key, int index, String value) { 1087 return lset(SafeEncoder.encode(key), index, 1088 SafeEncoder.encode(value)); 1089 } 1090 1091 /** 1092 * 在value的相对位置插入记录 1093 * 1094 * @param key 1095 * @param LIST_POSITION 1096 * 前面插入或后面插入 1097 * @param String 1098 * pivot 相对位置的内容 1099 * @param String 1100 * value 插入的内容 1101 * @return 记录总数 1102 * */ 1103 public long linsert(String key, LIST_POSITION where, String pivot, 1104 String value) { 1105 return linsert(SafeEncoder.encode(key), where, 1106 SafeEncoder.encode(pivot), SafeEncoder.encode(value)); 1107 } 1108 1109 /** 1110 * 在指定位置插入记录 1111 * 1112 * @param String 1113 * key 1114 * @param LIST_POSITION 1115 * 前面插入或后面插入 1116 * @param byte[] pivot 相对位置的内容 1117 * @param byte[] value 插入的内容 1118 * @return 记录总数 1119 * */ 1120 public long linsert(byte[] key, LIST_POSITION where, byte[] pivot, 1121 byte[] value) { 1122 Jedis jedis = getJedis(); 1123 long count = jedis.linsert(key, where, pivot, value); 1124 jedis.close(); 1125 return count; 1126 } 1127 1128 /** 1129 * 获取List中指定位置的值 1130 * 1131 * @param String 1132 * key 1133 * @param int index 位置 1134 * @return 值 1135 * **/ 1136 public String lindex(String key, int index) { 1137 return SafeEncoder.encode(lindex(SafeEncoder.encode(key), index)); 1138 } 1139 1140 /** 1141 * 获取List中指定位置的值 1142 * 1143 * @param byte[] key 1144 * @param int index 位置 1145 * @return 值 1146 * **/ 1147 public byte[] lindex(byte[] key, int index) { 1148 // ShardedJedis sjedis = getShardedJedis(); 1149 Jedis sjedis = getJedis(); 1150 byte[] value = sjedis.lindex(key, index); 1151 sjedis.close(); 1152 return value; 1153 } 1154 1155 /** 1156 * 将List中的第一条记录移出List 1157 * 1158 * @param String 1159 * key 1160 * @return 移出的记录 1161 * */ 1162 public String lpop(String key) { 1163 return SafeEncoder.encode(lpop(SafeEncoder.encode(key))); 1164 } 1165 1166 /** 1167 * 将List中的第一条记录移出List 1168 * 1169 * @param byte[] key 1170 * @return 移出的记录 1171 * */ 1172 public byte[] lpop(byte[] key) { 1173 Jedis jedis = getJedis(); 1174 byte[] value = jedis.lpop(key); 1175 jedis.close(); 1176 return value; 1177 } 1178 1179 /** 1180 * 将List中最后第一条记录移出List 1181 * 1182 * @param byte[] key 1183 * @return 移出的记录 1184 * */ 1185 public String rpop(String key) { 1186 Jedis jedis = getJedis(); 1187 String value = jedis.rpop(key); 1188 jedis.close(); 1189 return value; 1190 } 1191 1192 /** 1193 * 向List尾部追加记录 1194 * 1195 * @param String 1196 * key 1197 * @param String 1198 * value 1199 * @return 记录总数 1200 * */ 1201 public long lpush(String key, String value) { 1202 return lpush(SafeEncoder.encode(key), SafeEncoder.encode(value)); 1203 } 1204 1205 /** 1206 * 向List头部追加记录 1207 * 1208 * @param String 1209 * key 1210 * @param String 1211 * value 1212 * @return 记录总数 1213 * */ 1214 public long rpush(String key, String value) { 1215 Jedis jedis = getJedis(); 1216 long count = jedis.rpush(key, value); 1217 jedis.close(); 1218 return count; 1219 } 1220 1221 /** 1222 * 向List头部追加记录 1223 * 1224 * @param String 1225 * key 1226 * @param String 1227 * value 1228 * @return 记录总数 1229 * */ 1230 public long rpush(byte[] key, byte[] value) { 1231 Jedis jedis = getJedis(); 1232 long count = jedis.rpush(key, value); 1233 jedis.close(); 1234 return count; 1235 } 1236 1237 /** 1238 * 向List中追加记录 1239 * 1240 * @param byte[] key 1241 * @param byte[] value 1242 * @return 记录总数 1243 * */ 1244 public long lpush(byte[] key, byte[] value) { 1245 Jedis jedis = getJedis(); 1246 long count = jedis.lpush(key, value); 1247 jedis.close(); 1248 return count; 1249 } 1250 1251 /** 1252 * 获取指定范围的记录,可以做为分页使用 1253 * 1254 * @param String 1255 * key 1256 * @param long start 1257 * @param long end 1258 * @return List 1259 * */ 1260 public List<String> lrange(String key, long start, long end) { 1261 // ShardedJedis sjedis = getShardedJedis(); 1262 Jedis sjedis = getJedis(); 1263 List<String> list = sjedis.lrange(key, start, end); 1264 sjedis.close(); 1265 return list; 1266 } 1267 1268 /** 1269 * 获取指定范围的记录,可以做为分页使用 1270 * 1271 * @param byte[] key 1272 * @param int start 1273 * @param int end 如果为负数,则尾部开始计算 1274 * @return List 1275 * */ 1276 public List<byte[]> lrange(byte[] key, int start, int end) { 1277 // ShardedJedis sjedis = getShardedJedis(); 1278 Jedis sjedis = getJedis(); 1279 List<byte[]> list = sjedis.lrange(key, start, end); 1280 sjedis.close(); 1281 return list; 1282 } 1283 1284 /** 1285 * 删除List中c条记录,被删除的记录值为value 1286 * 1287 * @param byte[] key 1288 * @param int c 要删除的数量,如果为负数则从List的尾部检查并删除符合的记录 1289 * @param byte[] value 要匹配的值 1290 * @return 删除后的List中的记录数 1291 * */ 1292 public long lrem(byte[] key, int c, byte[] value) { 1293 Jedis jedis = getJedis(); 1294 long count = jedis.lrem(key, c, value); 1295 jedis.close(); 1296 return count; 1297 } 1298 1299 /** 1300 * 删除List中c条记录,被删除的记录值为value 1301 * 1302 * @param String 1303 * key 1304 * @param int c 要删除的数量,如果为负数则从List的尾部检查并删除符合的记录 1305 * @param String 1306 * value 要匹配的值 1307 * @return 删除后的List中的记录数 1308 * */ 1309 public long lrem(String key, int c, String value) { 1310 return lrem(SafeEncoder.encode(key), c, SafeEncoder.encode(value)); 1311 } 1312 1313 /** 1314 * 算是删除吧,只保留start与end之间的记录 1315 * 1316 * @param byte[] key 1317 * @param int start 记录的开始位置(0表示第一条记录) 1318 * @param int end 记录的结束位置(如果为-1则表示最后一个,-2,-3以此类推) 1319 * @return 执行状态码 1320 * */ 1321 public String ltrim(byte[] key, int start, int end) { 1322 Jedis jedis = getJedis(); 1323 String str = jedis.ltrim(key, start, end); 1324 jedis.close(); 1325 return str; 1326 } 1327 1328 /** 1329 * 算是删除吧,只保留start与end之间的记录 1330 * 1331 * @param String 1332 * key 1333 * @param int start 记录的开始位置(0表示第一条记录) 1334 * @param int end 记录的结束位置(如果为-1则表示最后一个,-2,-3以此类推) 1335 * @return 执行状态码 1336 * */ 1337 public String ltrim(String key, int start, int end) { 1338 return ltrim(SafeEncoder.encode(key), start, end); 1339 } 1340 } 1341 1342 }
redis相关配置信息(spring-redis.xml):配置redis信息,连接池,工具类等:
1 <beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 3 xsi:schemaLocation="http://www.springframework.org/schema/beans 4 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 5 http://www.springframework.org/schema/context 6 http://www.springframework.org/schema/context/spring-context-3.2.xsd"> 7 <!-- Redis连接池配置 --> 8 <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> 9 <!-- 控制一个pool能分配多少个jedis实例 --> 10 <property name="maxTotal" value="${redis.pool.maxActive}" /> 11 <!-- 连接池中最多空闲多少个maxIdle个连接,这里为20,表示即使没有数据库连接时依然可以保持20空闲的连接,而不被清除,处于待命状态,随时连接 --> 12 <property name="maxIdle" value="${redis.pool.maxIdle}" /> 13 <!-- 最大等待时间,当没有可用连接时,连接池等待连接被归还的最大时间(以毫秒计数),超过时间即抛出异常 --> 14 <property name="maxWaitMillis" value="${redis.pool.maxWait}" /> 15 <!-- 在获取连接时,检查有效性 --> 16 <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> 17 </bean> 18 <!-- 创建Redis连接池,并做相关配置 --> 19 <bean id="jedisWritePool" class="com.swpu.o2o.cache.JedisPoolWriper" 20 depends-on="jedisPoolConfig"> 21 <constructor-arg index="0" ref="jedisPoolConfig" /> 22 <constructor-arg index="1" value="${redis.hostname}" /> 23 <constructor-arg index="2" value="${redis.port}" type="int" /> 24 </bean> 25 <!-- 创建Redis工具类,封装好Redis的连接以进行相关操作 --> 26 <bean id="jedisUtil" class="com.swpu.o2o.cache.JedisUtil" 27 scope="singleton"> 28 <property name="jedisPool"> 29 <ref bean="jedisWritePool" /> 30 </property> 31 </bean> 32 <bean id="jedisKeys" class="com.swpu.o2o.cache.JedisUtil$Keys" 33 scope="singleton"> 34 <constructor-arg ref="jedisUtil"></constructor-arg> 35 </bean> 36 <bean id="jedisStrings" class="com.swpu.o2o.cache.JedisUtil$Strings" 37 scope="singleton"> 38 <constructor-arg ref="jedisUtil"></constructor-arg> 39 </bean> 40 <bean id="jedisLists" class="com.swpu.o2o.cache.JedisUtil$Lists" 41 scope="singleton"> 42 <constructor-arg ref="jedisUtil"></constructor-arg> 43 </bean> 44 <bean id="jedisSets" class="com.swpu.o2o.cache.JedisUtil$Sets" 45 scope="singleton"> 46 <constructor-arg ref="jedisUtil"></constructor-arg> 47 </bean> 48 <bean id="jedisHash" class="com.swpu.o2o.cache.JedisUtil$Hash" 49 scope="singleton"> 50 <constructor-arg ref="jedisUtil"></constructor-arg> 51 </bean> 52 53 </beans>
三.redis的使用
1.redis缓存相应数据例子(简单实现,未设置过期时间):
1.1redis缓存地区列表信息(Service):
1 package com.swpu.o2o.service.impl; 2 3 import java.io.IOException; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 import org.slf4j.Logger; 8 import org.slf4j.LoggerFactory; 9 import org.slf4j.LoggerFactory; 10 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.stereotype.Service; 12 import org.springframework.transaction.annotation.Transactional; 13 14 import com.fasterxml.jackson.core.JsonParseException; 15 import com.fasterxml.jackson.core.JsonProcessingException; 16 import com.fasterxml.jackson.databind.JavaType; 17 import com.fasterxml.jackson.databind.JsonMappingException; 18 import com.fasterxml.jackson.databind.ObjectMapper; 19 import com.swpu.o2o.cache.JedisUtil; 20 import com.swpu.o2o.dao.AreaDao; 21 import com.swpu.o2o.entity.Area; 22 import com.swpu.o2o.exceptions.AreaOperationException; 23 import com.swpu.o2o.service.AreaService; 24 25 @Service 26 @Transactional 27 public class AreaSeriviceImpl implements AreaService{ 28 @Autowired 29 private AreaDao areaDao; 30 @Autowired 31 //redis键对象 32 private JedisUtil.Keys jedisKeys; 33 @Autowired 34 //redis字符串对象 35 private JedisUtil.Strings jedisStrings; 36 //区域信息key 37 private static String AREALISTKEY="arealist"; 38 //日志 39 private Logger logger=LoggerFactory.getLogger(AreaSeriviceImpl.class); 40 @Override 41 public List<Area> getAreaList() { 42 String key=AREALISTKEY; 43 List<Area> areaList=null; 44 ObjectMapper mapper=new ObjectMapper(); 45 if(!jedisKeys.exists(key)){ 46 areaList=areaDao.queryArea(); 47 String jsonString; 48 try { 49 //转换为字符串 50 jsonString = mapper.writeValueAsString(areaList); 51 } catch (JsonProcessingException e) { 52 // TODO Auto-generated catch block 53 e.printStackTrace(); 54 logger.error(e.getMessage()); 55 throw new AreaOperationException(e.getMessage()); 56 } 57 //设置对应键值(字符串) 58 jedisStrings.set(key, jsonString); 59 60 } 61 else{ 62 //获取对应值 63 String jsonString=jedisStrings.get(key); 64 JavaType javaType=mapper.getTypeFactory().constructParametricType(ArrayList.class, Area.class); 65 try { 66 //获取为对应对象 67 areaList=mapper.readValue(jsonString, javaType); 68 } catch (JsonParseException e) { 69 e.printStackTrace(); 70 logger.error(e.getMessage()); 71 throw new AreaOperationException(e.getMessage()); 72 } catch (JsonMappingException e) { 73 e.printStackTrace(); 74 logger.error(e.getMessage()); 75 throw new AreaOperationException(e.getMessage()); 76 } catch (IOException e) { 77 e.printStackTrace(); 78 logger.error(e.getMessage()); 79 throw new AreaOperationException(e.getMessage()); 80 } 81 } 82 return areaList; 83 } 84 85 86 }
1.2redis缓存轮播图信息(Service):
1 package com.swpu.o2o.service.impl; 2 3 import java.io.IOException; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 import org.slf4j.Logger; 8 import org.slf4j.LoggerFactory; 9 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.stereotype.Service; 11 12 import com.fasterxml.jackson.core.JsonParseException; 13 import com.fasterxml.jackson.core.JsonProcessingException; 14 import com.fasterxml.jackson.databind.JavaType; 15 import com.fasterxml.jackson.databind.JsonMappingException; 16 import com.fasterxml.jackson.databind.ObjectMapper; 17 import com.swpu.o2o.cache.JedisUtil; 18 import com.swpu.o2o.dao.HeadLineDao; 19 import com.swpu.o2o.entity.HeadLine; 20 import com.swpu.o2o.exceptions.AreaOperationException; 21 import com.swpu.o2o.service.HeadLineService; 22 23 @Service 24 public class HeadLineServiceImpl implements HeadLineService{ 25 @Autowired 26 private HeadLineDao headLineDao; 27 @Autowired 28 private JedisUtil.Keys jedisKeys; 29 @Autowired 30 private JedisUtil.Strings jedisStrings; 31 //头条缓存中对应的键 32 private static String HEADLISTKEY="headlist"; 33 private Logger logger=LoggerFactory.getLogger(HeadLineServiceImpl.class); 34 35 @Override 36 public List<HeadLine> getHeadLineList(HeadLine headLineCondition) throws IOException { 37 String key=HEADLISTKEY; 38 List<HeadLine> headlist=null; 39 //定义jackson数据转换操作类 40 ObjectMapper mapper=new ObjectMapper(); 41 //拼接redis的key(轮播图有两种状态:0【禁用】和1【可用】) 42 if(headLineCondition!=null&&headLineCondition.getEnableStatus()!=null){ 43 key=key+"_"+headLineCondition.getEnableStatus(); 44 } 45 //判断key是否存在 46 if(!jedisKeys.exists(key)){ 47 //不存在,则调用Dao层从mysql取出相应数据 48 headlist=headLineDao.queryHeadLine(headLineCondition); 49 //将相关实体类集合转换为string,存入redis里面对应的key中 50 String jsonString; 51 try { 52 //转换为字符串 53 jsonString = mapper.writeValueAsString(headlist); 54 } catch (JsonProcessingException e) { 55 e.printStackTrace(); 56 logger.error(e.getMessage()); 57 throw new AreaOperationException(e.getMessage()); 58 } 59 jedisStrings.set(key, jsonString); 60 61 } 62 else{ 63 //该key存在,直接从redis将数据取出 64 String jsonString=jedisStrings.get(key); 65 //指定要将将string转换为相应的集合类型 66 JavaType javaType=mapper.getTypeFactory().constructParametricType(ArrayList.class, HeadLine.class); 67 try { 68 //将相关key对应的值string取出来转换为相应的对象的实体类集合 69 headlist=mapper.readValue(jsonString, javaType); 70 } catch (JsonParseException e) { 71 e.printStackTrace(); 72 logger.error(e.getMessage()); 73 throw new AreaOperationException(e.getMessage()); 74 } catch (JsonMappingException e) { 75 e.printStackTrace(); 76 logger.error(e.getMessage()); 77 throw new AreaOperationException(e.getMessage()); 78 } catch (IOException e) { 79 e.printStackTrace(); 80 logger.error(e.getMessage()); 81 throw new AreaOperationException(e.getMessage()); 82 } 83 } 84 return headlist; 85 } 86 87 }
1.3redis缓存商品类别信息(Service):
1 package com.swpu.o2o.service.impl; 2 3 import java.io.IOException; 4 import java.util.List; 5 6 import org.slf4j.Logger; 7 import org.slf4j.LoggerFactory; 8 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.stereotype.Service; 10 11 import com.fasterxml.jackson.core.JsonParseException; 12 import com.fasterxml.jackson.core.JsonProcessingException; 13 import com.fasterxml.jackson.databind.JavaType; 14 import com.fasterxml.jackson.databind.JsonMappingException; 15 import com.fasterxml.jackson.databind.ObjectMapper; 16 import com.swpu.o2o.cache.JedisUtil; 17 import com.swpu.o2o.dao.ShopCategoryDao; 18 import com.swpu.o2o.entity.ShopCategory; 19 import com.swpu.o2o.exceptions.ShopOperationException; 20 import com.swpu.o2o.service.ShopCategoryService; 21 22 @Service 23 public class ShopCategoryServiceImpl implements ShopCategoryService { 24 @Autowired 25 private ShopCategoryDao shopCategoryDao; 26 @Autowired 27 private JedisUtil.Keys jedisKeys; 28 @Autowired 29 private JedisUtil.Strings jedisStrings; 30 31 private static String SCLISTKEY = "shopcategorylist"; 32 private static Logger logger = LoggerFactory.getLogger(ShopCategoryServiceImpl.class); 33 34 @Override 35 public List<ShopCategory> getShopCategoeyList(ShopCategory shopCategoryCondition) { 36 // 定义redis的key前缀 37 String key = SCLISTKEY; 38 // 定义接收对象 39 List<ShopCategory> shopCategoryList = null; 40 // 定义jackson数据转换操作类 41 ObjectMapper mapper = new ObjectMapper(); 42 // 拼接出redis的key 43 if (shopCategoryCondition == null) { 44 // 若查询条件为空,则列出所有首页大类,即parentId为空的店铺类别 45 key = key + "_allfirstlevel"; 46 } else if (shopCategoryCondition != null && shopCategoryCondition.getParent() != null 47 && shopCategoryCondition.getParent().getShopCategoryId() != null) { 48 //若parentId不为空,则列出所有该parentId下的所有子类别 49 key=key+"_parent"+shopCategoryCondition.getParent().getShopCategoryId(); 50 51 } 52 else if(shopCategoryCondition!=null){ 53 //列出所有子类别,不管属于哪个类,都列出来 54 key=key+"_allsecendlevel"; 55 } 56 //判断key是否存在 57 if(!jedisKeys.exists(key)){ 58 //若不存在,则从数据库中取出相应数据 59 shopCategoryList=shopCategoryDao.queryShopCategory(shopCategoryCondition); 60 //将相关的实体类集合转换成string,存入redis里面对应的key 61 String jsonString; 62 try{ 63 jsonString=mapper.writeValueAsString(shopCategoryList); 64 } 65 catch(JsonProcessingException e){ 66 e.printStackTrace(); 67 logger.error(e.getMessage()); 68 throw new ShopOperationException(e.getMessage()); 69 70 } 71 jedisStrings.set(key, jsonString); 72 73 } 74 else{ 75 //键存在 76 String jsonString=jedisStrings.get(key); 77 //指定要将值转换为的集合类型 78 JavaType javaType=mapper.getTypeFactory().constructParametricType(String.class, ShopCategory.class); 79 try { 80 //将相关key中的value里的String类型转换为对象的实体类集合 81 shopCategoryList=mapper.readValue(jsonString, javaType); 82 } catch (JsonParseException e) { 83 e.printStackTrace(); 84 logger.error(e.getMessage()); 85 throw new ShopOperationException(e.getMessage()); 86 } catch (JsonMappingException e) { 87 e.printStackTrace(); 88 logger.error(e.getMessage()); 89 throw new ShopOperationException(e.getMessage()); 90 } catch (IOException e) { 91 e.printStackTrace(); 92 logger.error(e.getMessage()); 93 throw new ShopOperationException(e.getMessage()); 94 } 95 } 96 return shopCategoryList; 97 } 98 99 }
注意:
1.连接时需要检查redis是否可用,如果需要远程连接(注意是否绑定了IP,是则注销或者将IP修改为0.0.0.0),需要修改redis配置文件将保护状态(protected-mode修改为no),然后重启;
2.注意redis的key不能重复,否则值会覆盖。
2.删除相应键值对(把键移动到service接口中,便于使用):
2.1定义缓存删除接口:
1 package com.swpu.o2o.service; 2 3 public interface CacheService { 4 /** 5 * 根据key前缀删除匹配该模式下的所有key-value(如shopcategory,则以该字符串开头的所有键值都会删除) 6 * @param keyPrefix 7 */ 8 void removeFromCatche(String keyPrefix); 9 10 }
2.2实现缓存删除接口:
1 package com.swpu.o2o.service.impl; 2 3 import java.util.Set; 4 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.stereotype.Service; 7 8 import com.swpu.o2o.cache.JedisUtil; 9 import com.swpu.o2o.service.CacheService; 10 11 @Service 12 public class CacheServiceImpl implements CacheService { 13 // 定义操作key的对象 14 @Autowired 15 private JedisUtil.Keys jedisKeys; 16 17 @Override 18 public void removeFromCatche(String keyPrefix) { 19 // 匹配获取所有以字符串keyPrefix开头的键的集合 20 Set<String> keySet = jedisKeys.keys(keyPrefix + "*"); 21 for (String key : keySet) { 22 // 遍历删除集合中对应键 23 jedisKeys.del(key); 24 } 25 } 26 27 }