为了减少数据库访问频率,提高查询速度,今天讲一下 spring boot mybatis 怎么集成 redis 缓存。
第一步:添加 redis 相关 jar 包依赖
这里我只贴出集成 redis 缓存所需要的 jar 包,至于链接数据库,和基本的项目启动请参考
Spring boot 2 mybatis 配置
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
至于 jar 包 spring-boot-starter-cache
至少在版本 2.1.3 可以不用引用,2.1.3 版本 jar 包 spring-boot-starter-data-redis
已经自带 cache 所需要的 jar 包,不用重复引用。
第二步:添加 redis 链接数据库配置文件
spring:
# 数据库连接
#datasource:
# password: 111111
# url: jdbc:mysql://120.77.241.43:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
# username: root
# redis
redis:
host: 127.0.0.1
port: 6300
password: 123
# Redis数据库索引(默认为0)
database: 0
#连接超时时间(毫秒)
timeout: 10000
jedis: #一些常规配置
pool:
# 连接池中的最大空闲连接
max-idle: 60
# 连接池中的最小空闲连接
min-idle: 30
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 60000
# 连接池最大连接数(使用负值表示没有限制)
max-active: 200
第三步:添加 RedisConfig 配置类
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean(name = "cacheKeyGenerator")
@Primary//@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
public KeyGenerator keyGenerator() {
return (target, method, params) -> CacheHashCode.of(params);
}
/**
* spring boot 缓存默认配置
* @param factory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
return RedisCacheManager.builder(factory)
//默认缓存时间
.cacheDefaults(getRedisCacheConfigurationWithTtl(60))
.transactionAware()
//自定义缓存时间
.withInitialCacheConfigurations(getRedisCacheConfigurationMap())
.build();
}
/**
* 自定义缓存时间
* @return
*/
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
redisCacheConfigurationMap.put("test", this.getRedisCacheConfigurationWithTtl(3000));
return redisCacheConfigurationMap;
}
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(seconds))//定义默认的cache time-to-live.(缓存存储有效时间)
.disableCachingNullValues()//静止缓存为空
//此处定义了cache key的前缀, 避免公司不同项目之间的key名称冲突.
.computePrefixWith(cacheName -> "api".concat(":").concat(cacheName).concat(":"))
//定义key和value的序列化协议, 同时的hash key和hash value也被定义.
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(createJackson2JsonRedisSerializer()))
//自定义key的生成策略, 将方法参数转换为hashcode, 作为redis key. 需要做两个事情, 一个是添加一个自定义的ConversionService, 另一个是需要自定义一个KeyGenerator.
.withConversionService(new CacheKeyConversionService());
}
/**
* 创建redisTemplate工具
* @param factory
* @return
*/
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
template.setKeySerializer(new StringRedisSerializer());//设置key序列化类,否则key前面会多了一些乱码
template.setValueSerializer(createJackson2JsonRedisSerializer());//设置value序列化
template.setHashKeySerializer(createJackson2JsonRedisSerializer());//设置 hash key 序列化
template.setHashValueSerializer(createJackson2JsonRedisSerializer());//设置 hash value 序列化
template.setEnableTransactionSupport(true);//设置redis支持数据库的事务
template.afterPropertiesSet();//初始化设置并且生效
return template;
}
/**
* 创建redis序列化
* @return
*/
private RedisSerializer<Object> createJackson2JsonRedisSerializer() {
ObjectMapper objectMapper = new ObjectMapper();
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return jackson2JsonRedisSerializer;
}
}
public class CacheKeyConversionService implements ConversionService {
@Override
public boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType) {
return true;
}
@Override
public boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType) {
return true;
}
@Nullable
@Override
public <T> T convert(@Nullable Object source, Class<T> targetType) {
return (T) convert(source);
}
@Nullable
@Override
public Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) {
return convert(source);
}
private Object convert(Object source) {
if (source instanceof CacheHashCode) {
return ((CacheHashCode) source).hashString();
}
return CacheHashCode.of(source).hashString();
}
}
第四步:在需要存入 redis 缓存的方法上添加注解
注解介绍
- @Cacheable
获取缓存 如果有缓存 直接返回
属性 | 类型 | 功能 |
---|---|---|
value | String[] | 缓存的名称 和 cacheNames 功能一样 |
cacheNames | String[] | 缓存的名称和 value 功能一样 |
key | String | 缓存 key 的值、默认是以所有的参数作为 key、也可以直接配置 keyGenerator |
keyGenerator | String | 缓存 key 的生成器 |
cacheManager | String | 配置使用那个缓存管理器、和 cacheResolver 排斥 |
cacheResolver | String | 定义使用那个拦截器、和 cacheManager 互斥 |
condition | String | 根据 spel 表达式来可以配置什么条件下进行缓存 默认全部缓存 |
unless | String | 和 condition 相反 |
sync | boolean | 是否开启同步功能、默认不开启 |
- @CachePut
执行并且更新缓存相关 不管如何 肯定会执行方法 然后返回 这样可以更新缓存的内容
属性 | 类型 | 功能 |
---|---|---|
value | String[] | 缓存的名称 和 cacheNames 功能一样 |
cacheNames | String[] | 缓存的名称和 value 功能一样 |
key | String | 缓存 key 的值、默认是以所有的参数作为 key、也可以直接配置 keyGenerator |
keyGenerator | String | 缓存 key 的生成器 |
cacheManager | String | 配置使用那个缓存管理器、和 cacheResolver 排斥 |
cacheResolver | String | 定义使用那个拦截器、和 cacheManager 互斥 |
condition | String | 根据 spel 表达式来可以配置什么条件下进行缓存 默认全部缓存 |
unless | String | 和 condition 相反 |
- @CacheEvict
删除缓存相关
属性 | 类型 | 功能 |
---|---|---|
value | String[] | 缓存的名称 和 cacheNames 功能一样 |
cacheNames | String[] | 缓存的名称和 value 功能一样 |
key | String | 缓存 key 的值、默认是以所有的参数作为 key、也可以直接配置 keyGenerator |
keyGenerator | String | 缓存 key 的生成器 |
cacheManager | String | 配置使用那个缓存管理器、和 cacheResolver 排斥 |
cacheResolver | String | 定义使用那个拦截器、和 cacheManager 互斥 |
condition | String | 根据 spel 表达式来可以配置什么条件下进行缓存 默认全部缓存 |
allEntries | boolean | 是否删除所有键的缓存 默认不删除 |
beforeInvocation | boolean | 是否在调用此方法前 删除缓存 |
- @CacheConfig
在类级别统一的配置缓存公共配置
属性 | 类型 | 功能 |
---|---|---|
cacheNames | String[] | 缓存的名称和 value 功能一样 |
keyGenerator | String | 缓存 key 的生成器 |
cacheManager | String | 配置使用那个缓存管理器、和 cacheResolver 排斥 |
cacheResolver | String | 定义使用那个拦截器、和 cacheManager 互斥 |
- @EnableCaching
开启缓存以及缓存的全局配置
属性 | 类型 | 功能 |
---|---|---|
proxyTargetClass | boolean | 是否要基于 cglib 生成代理去实现缓存 |
mode | AdviceMode | 配置那种模式去实现缓存、默认是 AdviceMode.PROXY 可以切换为 AdviceMode#ASPECTJ |
order | int | 设置缓存管理器执行的顺序 |
- @Caching
对多个缓存组的配置
属性 | 类型 | 功能 |
---|---|---|
cacheable | Cacheable | 配置获取缓存相关的配置 |
put | CachePut | 配置如何更新缓存的相关配置 |
evict | CacheEvict | 配置如何删除缓存的相关配置 |
第五步:在启动类配置开启缓存
第六步:运行查看效果
controller
查看 redis 客户端存储的数据
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于