作者 王勇

使用redis作为mybatis的二级缓存

@@ -3,6 +3,7 @@ package com.sunyo.wlpt.message.bus.service; @@ -3,6 +3,7 @@ package com.sunyo.wlpt.message.bus.service;
3 import org.mybatis.spring.annotation.MapperScan; 3 import org.mybatis.spring.annotation.MapperScan;
4 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.SpringApplication;
5 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.boot.autoconfigure.SpringBootApplication;
  6 +import org.springframework.cache.annotation.EnableCaching;
6 import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 7 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
7 import org.springframework.cloud.openfeign.EnableFeignClients; 8 import org.springframework.cloud.openfeign.EnableFeignClients;
8 import org.springframework.scheduling.annotation.EnableAsync; 9 import org.springframework.scheduling.annotation.EnableAsync;
@@ -12,6 +13,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @@ -12,6 +13,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
12 /** 13 /**
13 * @author 子诚 14 * @author 子诚
14 */ 15 */
  16 +@EnableCaching
15 @SpringBootApplication 17 @SpringBootApplication
16 @MapperScan("com.sunyo.wlpt.message.bus.service.mapper") 18 @MapperScan("com.sunyo.wlpt.message.bus.service.mapper")
17 @EnableFeignClients 19 @EnableFeignClients
  1 +package com.sunyo.wlpt.message.bus.service.cache;
  2 +
  3 +import org.springframework.beans.BeansException;
  4 +import org.springframework.context.ApplicationContext;
  5 +import org.springframework.context.ApplicationContextAware;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +/**
  9 + * @author 子诚
  10 + * Description:用来获取springboot创建好的工厂
  11 + * 时间:2020/8/6 9:31
  12 + */
  13 +@Component
  14 +public class ApplicationContextUtils implements ApplicationContextAware {
  15 +
  16 + /**
  17 + * 保留下来工厂
  18 + */
  19 + private static ApplicationContext context;
  20 +
  21 + /**
  22 + * 将创建好工厂以参数形式传递给这个类
  23 + *
  24 + * @param applicationContext 上下文
  25 + * @throws BeansException
  26 + */
  27 + @Override
  28 + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
  29 + {
  30 + context = applicationContext;
  31 + }
  32 +
  33 + /**
  34 + * 提供在工厂中获取对象的方法 例如:RedisTemplate redisTemplate
  35 + *
  36 + * @param beanName bean的名称
  37 + * @return
  38 + */
  39 + public static Object getBean(String beanName)
  40 + {
  41 + return context.getBean(beanName);
  42 + }
  43 +
  44 +}
  45 +
  46 +
  1 +package com.sunyo.wlpt.message.bus.service.cache;
  2 +
  3 +import org.apache.ibatis.cache.Cache;
  4 +import org.slf4j.Logger;
  5 +import org.slf4j.LoggerFactory;
  6 +import org.springframework.data.redis.core.RedisTemplate;
  7 +import org.springframework.data.redis.serializer.StringRedisSerializer;
  8 +import org.springframework.util.DigestUtils;
  9 +
  10 +import java.util.concurrent.TimeUnit;
  11 +import java.util.concurrent.locks.ReadWriteLock;
  12 +import java.util.concurrent.locks.ReentrantReadWriteLock;
  13 +
  14 +
  15 +/**
  16 + * @author 子诚
  17 + * Description:自定义Redis作为mybatis二级缓存实现
  18 + * 时间:2020/8/6 9:37
  19 + */
  20 +public class RedisCache implements Cache {
  21 +
  22 + /**
  23 + * slf4j的日志记录器
  24 + */
  25 + private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);
  26 +
  27 + /**
  28 + * 用于事务性缓存操作的读写锁
  29 + */
  30 + private static final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
  31 +
  32 + /**
  33 + * 缓存对象的是失效时间,30分钟
  34 + */
  35 + private static final long CACHE_TIME_IN_MINT = 30;
  36 +
  37 + /**
  38 + * 当前放入缓存的mapper的namespace
  39 + */
  40 + private final String id;
  41 +
  42 + /**
  43 + * 必须存在构造方法
  44 + */
  45 + public RedisCache(String id)
  46 + {
  47 + this.id = id;
  48 + }
  49 +
  50 + /**
  51 + * 返回cache唯一标识
  52 + */
  53 + @Override
  54 + public String getId()
  55 + {
  56 + return this.id;
  57 + }
  58 +
  59 + /**
  60 + * 缓存放入值 redis RedisTemplate StringRedisTemplate
  61 + *
  62 + * @param key hash_key
  63 + * @param value hash_value
  64 + */
  65 + @Override
  66 + public void putObject(Object key, Object value)
  67 + {
  68 + RedisTemplate redisTemplate = getRedisTemplate();
  69 + // 使用redis的hash类型作为缓存存储模型
  70 + redisTemplate.opsForHash().put(id.toString(), key.toString(), value);
  71 + redisTemplate.expire(id.toString(), CACHE_TIME_IN_MINT, TimeUnit.MINUTES);
  72 + }
  73 +
  74 + /**
  75 + * 缓存中中获取数据
  76 + */
  77 + @Override
  78 + public Object getObject(Object key)
  79 + {
  80 + RedisTemplate redisTemplate = getRedisTemplate();
  81 + //根据key 从redis的hash类型中获取数据
  82 + return redisTemplate.opsForHash().get(id.toString(), key.toString());
  83 + }
  84 +
  85 + /**
  86 + * 注意:这个方法为mybatis保留方法 默认没有实现 后续版本可能会实现
  87 + *
  88 + * @param key hash_key
  89 + * @return
  90 + */
  91 + @Override
  92 + public Object removeObject(Object key)
  93 + {
  94 + RedisTemplate redisTemplate = getRedisTemplate();
  95 + redisTemplate.delete(key);
  96 + return null;
  97 + }
  98 +
  99 + @Override
  100 + public void clear()
  101 + {
  102 + logger.info("清空->{}<-缓存", id);
  103 + RedisTemplate redisTemplate = getRedisTemplate();
  104 + // 清空 namespace
  105 + redisTemplate.delete(id.toString());
  106 + }
  107 +
  108 + /**
  109 + * 用来计算缓存数量
  110 + */
  111 + @Override
  112 + public int getSize()
  113 + {
  114 + RedisTemplate redisTemplate = getRedisTemplate();
  115 + // 获取hash中key value数量
  116 + return redisTemplate.opsForHash().size(id.toString()).intValue();
  117 + }
  118 +
  119 + /**
  120 + * 封装redisTemplate
  121 + *
  122 + * @return RedisTemplate
  123 + */
  124 + private RedisTemplate getRedisTemplate()
  125 + {
  126 + //通过application工具类获取redisTemplate
  127 + RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
  128 + redisTemplate.setKeySerializer(new StringRedisSerializer());
  129 + redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  130 + return redisTemplate;
  131 + }
  132 +
  133 + /**
  134 + * 封装一个对key进行md5处理方法
  135 + */
  136 + private String getKeyToMD5(String key)
  137 + {
  138 + return DigestUtils.md5DigestAsHex(key.getBytes());
  139 + }
  140 +
  141 + @Override
  142 + public ReadWriteLock getReadWriteLock()
  143 + {
  144 + return readWriteLock;
  145 + }
  146 +
  147 +}
  148 +
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.BusExchangeMapper"> 3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.BusExchangeMapper">
  4 + <!-- 使用Redis做mybatis的二级缓存 -->
  5 + <cache type="com.sunyo.wlpt.message.bus.service.cache.RedisCache"/>
4 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.BusExchange"> 6 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.BusExchange">
5 <!--@mbg.generated--> 7 <!--@mbg.generated-->
6 <!--@Table bus_exchange--> 8 <!--@Table bus_exchange-->
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.BusQueueMapper"> 3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.BusQueueMapper">
  4 + <!-- 使用Redis做mybatis的二级缓存 -->
  5 + <cache type="com.sunyo.wlpt.message.bus.service.cache.RedisCache"/>
4 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.BusQueue"> 6 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.BusQueue">
5 <!--@mbg.generated--> 7 <!--@mbg.generated-->
6 <!--@Table bus_queue--> 8 <!--@Table bus_queue-->
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.BusServerMapper"> 3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.BusServerMapper">
  4 + <!-- 使用Redis做mybatis的二级缓存 -->
  5 + <cache type="com.sunyo.wlpt.message.bus.service.cache.RedisCache"/>
4 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.BusServer"> 6 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.BusServer">
5 <!--@mbg.generated--> 7 <!--@mbg.generated-->
6 <!--@Table bus_server--> 8 <!--@Table bus_server-->
@@ -237,5 +239,4 @@ @@ -237,5 +239,4 @@
237 from bus_server 239 from bus_server
238 where server_name = #{serverName,jdbcType=VARCHAR} 240 where server_name = #{serverName,jdbcType=VARCHAR}
239 </select> 241 </select>
240 -  
241 </mapper> 242 </mapper>
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.RoutingKeyMapper"> 3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.RoutingKeyMapper">
  4 + <!-- 使用Redis做mybatis的二级缓存 -->
  5 + <cache type="com.sunyo.wlpt.message.bus.service.cache.RedisCache"/>
4 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.RoutingKey"> 6 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.RoutingKey">
5 <!--@mbg.generated--> 7 <!--@mbg.generated-->
6 <!--@Table routing_key--> 8 <!--@Table routing_key-->
1 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 1 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
2 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 2 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.UserMessageBindingMapper"> 3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.UserMessageBindingMapper">
  4 + <!-- 使用Redis做mybatis的二级缓存 -->
  5 + <cache type="com.sunyo.wlpt.message.bus.service.cache.RedisCache"/>
4 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.UserMessageBinding"> 6 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.UserMessageBinding">
5 <!--@mbg.generated--><!--@Table user_message_binding--> 7 <!--@mbg.generated--><!--@Table user_message_binding-->
6 <id column="id" jdbcType="VARCHAR" property="id"/> 8 <id column="id" jdbcType="VARCHAR" property="id"/>
@@ -65,7 +67,7 @@ @@ -65,7 +67,7 @@
65 where id = #{id,jdbcType=VARCHAR} 67 where id = #{id,jdbcType=VARCHAR}
66 </delete> 68 </delete>
67 69
68 -<!-- 根据服务器id,删除配置关系--> 70 + <!-- 根据服务器id,删除配置关系-->
69 <delete id="deleteByServerId" parameterType="java.lang.String"> 71 <delete id="deleteByServerId" parameterType="java.lang.String">
70 <!--@mbg.generated--> 72 <!--@mbg.generated-->
71 delete 73 delete
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.VirtualHostMapper"> 3 <mapper namespace="com.sunyo.wlpt.message.bus.service.mapper.VirtualHostMapper">
  4 + <!-- 使用Redis做mybatis的二级缓存 -->
  5 + <cache type="com.sunyo.wlpt.message.bus.service.cache.RedisCache"/>
4 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.VirtualHost"> 6 <resultMap id="BaseResultMap" type="com.sunyo.wlpt.message.bus.service.domain.VirtualHost">
5 <!--@mbg.generated--> 7 <!--@mbg.generated-->
6 <!--@Table virtual_host--> 8 <!--@Table virtual_host-->