本片文章续《Spring Boot 入门(九):集成Quartz定时任务》。本文主要基于redis实现了mybatis二级缓存。较redis缓存,mybaits自带缓存存在缺点(自行谷歌)。本文是基于docker安装redis主从模式。

(1)首先安装redis集群模式,建立redis目录,并编写主从模式docker-compose.yml文件

  1. 1 version: '3.1'
  2. 2 services:
  3. 3 master:
  4. 4 image: redis
  5. 5 container_name: redis-master
  6. 6 ports:
  7. 7 - 6379:6379
  8. 8
  9. 9 slave1:
  10. 10 image: redis
  11. 11 container_name: redis-slave-1
  12. 12 ports:
  13. 13 - 6380:6379
  14. 14 command: redis-server --slaveof redis-master 6379
  15. 15
  16. 16 slave2:
  17. 17 image: redis
  18. 18 container_name: redis-slave-2
  19. 19 ports:
  20. 20 - 6381:6379
  21. 21 command: redis-server --slaveof redis-master 6379

(2).启动 docker-compose up -d

(3).建立sentinel文件,并编写docker-compose.yml文件

  1. 1 version: '3.1'
  2. 2 services:
  3. 3 sentinel1:
  4. 4 image: redis
  5. 5 container_name: redis-sentinel-1
  6. 6 ports:
  7. 7 - 26379:26379
  8. 8 command: redis-sentinel /usr/local/etc/redis/sentinel.conf
  9. 9 volumes:
  10. 10 - ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf
  11. 11
  12. 12 sentinel2:
  13. 13 image: redis
  14. 14 container_name: redis-sentinel-2
  15. 15 ports:
  16. 16 - 26380:26379
  17. 17 command: redis-sentinel /usr/local/etc/redis/sentinel.conf
  18. 18 volumes:
  19. 19 - ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf
  20. 20
  21. 21 sentinel3:
  22. 22 image: redis
  23. 23 container_name: redis-sentinel-3
  24. 24 ports:
  25. 25 - 26381:26379
  26. 26 command: redis-sentinel /usr/local/etc/redis/sentinel.conf
  27. 27 volumes:
  28. 28 - ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
  29. 29

从模式需要sentinel的conf文件,我创建了3个容器,所以这里需要3份(sentinel1.conf sentinel2.conf sentinel3.conf),内容是一模一样

  1. 1 port 26379
  2. 2 dir /tmp
  3. 3 sentinel monitor mymaster 217.0.0.1 6379 2
  4. 4 sentinel down-after-milliseconds rmaster 30000
  5. 5 sentinel parallel-syncs mymaster 1
  6. 6 sentinel failover-timeout mymaster 180000
  7. 7 sentinel deny-scripts-reconfig yes

(4).启动:docker-compose up -d

(5).验证redis是否已经成功启动

进入容器:docker exec -it redis-sentinel-1 /bin/bash

连接redis:redis-cli -p 26379

如下图,表示启动成功

 

也可以通过桌面客户端查看是否启动成功,如图,我使用的RedisDesktopManager客户端

 

 

网上一大堆,根据自己需要选择合适的utils(有的utils中方法很全)

  1. 1 package com.learn.hello.system.utils;
  2. 2
  3. 3 import lombok.extern.slf4j.Slf4j;
  4. 4 import org.apache.ibatis.cache.Cache;
  5. 5 import org.springframework.data.redis.core.RedisCallback;
  6. 6 import org.springframework.data.redis.core.RedisTemplate;
  7. 7 import org.springframework.data.redis.core.ValueOperations;
  8. 8
  9. 9 import java.util.concurrent.TimeUnit;
  10. 10 import java.util.concurrent.locks.ReadWriteLock;
  11. 11 import java.util.concurrent.locks.ReentrantReadWriteLock;
  12. 12
  13. 13 /**
  14. 14 * @ClassName RedisCache
  15. 15 * @Deccription 通过redis实现mybaits的二级缓存
  16. 16 * @Author DZ
  17. 17 * @Date 2020/1/12 22:41
  18. 18 **/
  19. 19 @Slf4j
  20. 20 public class RedisCache implements Cache {
  21. 21
  22. 22 private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
  23. 23 private final String id; // cache instance id
  24. 24 private RedisTemplate redisTemplate;
  25. 25
  26. 26 private static final long EXPIRE_TIME_IN_MINUTES = 30; // redis过期时间
  27. 27
  28. 28 public RedisCache(String id) {
  29. 29 if (id == null) {
  30. 30 throw new IllegalArgumentException("Cache instances require an ID");
  31. 31 }
  32. 32 this.id = id;
  33. 33 }
  34. 34
  35. 35 @Override
  36. 36 public String getId() {
  37. 37 return id;
  38. 38 }
  39. 39
  40. 40 /**
  41. 41 * Put query result to redis
  42. 42 *
  43. 43 * @param key
  44. 44 * @param value
  45. 45 */
  46. 46 @Override
  47. 47 public void putObject(Object key, Object value) {
  48. 48 try {
  49. 49 RedisTemplate redisTemplate = getRedisTemplate();
  50. 50 ValueOperations opsForValue = redisTemplate.opsForValue();
  51. 51 opsForValue.set(key, value, EXPIRE_TIME_IN_MINUTES, TimeUnit.MINUTES);
  52. 52 log.debug("Put query result to redis");
  53. 53 } catch (Throwable t) {
  54. 54 log.error("Redis put failed", t);
  55. 55 }
  56. 56 }
  57. 57
  58. 58 /**
  59. 59 * Get cached query result from redis
  60. 60 *
  61. 61 * @param key
  62. 62 * @return
  63. 63 */
  64. 64 @Override
  65. 65 public Object getObject(Object key) {
  66. 66 try {
  67. 67 RedisTemplate redisTemplate = getRedisTemplate();
  68. 68 ValueOperations opsForValue = redisTemplate.opsForValue();
  69. 69 log.debug("Get cached query result from redis");
  70. 70 return opsForValue.get(key);
  71. 71 } catch (Throwable t) {
  72. 72 log.error("Redis get failed, fail over to db", t);
  73. 73 return null;
  74. 74 }
  75. 75 }
  76. 76
  77. 77 /**
  78. 78 * Remove cached query result from redis
  79. 79 *
  80. 80 * @param key
  81. 81 * @return
  82. 82 */
  83. 83 @Override
  84. 84 @SuppressWarnings("unchecked")
  85. 85 public Object removeObject(Object key) {
  86. 86 try {
  87. 87 RedisTemplate redisTemplate = getRedisTemplate();
  88. 88 redisTemplate.delete(key);
  89. 89 log.debug("Remove cached query result from redis");
  90. 90 } catch (Throwable t) {
  91. 91 log.error("Redis remove failed", t);
  92. 92 }
  93. 93 return null;
  94. 94 }
  95. 95
  96. 96 /**
  97. 97 * Clears this cache instance
  98. 98 */
  99. 99 @Override
  100. 100 public void clear() {
  101. 101 RedisTemplate redisTemplate = getRedisTemplate();
  102. 102 redisTemplate.execute((RedisCallback) connection -> {
  103. 103 connection.flushDb();
  104. 104 return null;
  105. 105 });
  106. 106 log.debug("Clear all the cached query result from redis");
  107. 107 }
  108. 108
  109. 109 /**
  110. 110 * This method is not used
  111. 111 *
  112. 112 * @return
  113. 113 */
  114. 114 @Override
  115. 115 public int getSize() {
  116. 116 return 0;
  117. 117 }
  118. 118
  119. 119 @Override
  120. 120 public ReadWriteLock getReadWriteLock() {
  121. 121 return readWriteLock;
  122. 122 }
  123. 123
  124. 124 private RedisTemplate getRedisTemplate() {
  125. 125 if (redisTemplate == null) {
  126. 126 redisTemplate = SpringContextHolder.getBean("redisTemplate");
  127. 127 }
  128. 128 return redisTemplate;
  129. 129 }
  130. 130 }
  1. @CacheNamespace(implementation = RedisCache.class)

例如:

  1. 1 @CacheNamespace(implementation = RedisCache.class)
  2. 2 public interface RoleMapper extends MyMapper<Role> {
  3. 3 List<Role> selectByCondition(ModelMap modelMap);
  4. 4
  5. 5 Role selectById(int id);
  6. 6
  7. 7 List<Role> selectAllRole();
  8. 8 }

这里也可以直接在MyMapper父接口中增加注解,这样,所有的接口就不需要单独增加这个注解(根据业务需要自行素选择)。

当进行CURD操作时,相关的检索sql语句就会缓存到redis,如图:

 

 当再次对相关数据进行CRUD时,就会走缓存

版权声明:本文为dz-boss原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/dz-boss/p/12190065.html