Springboot+Mybatis+redis实现二级缓存
Mybatis的二级缓存是多个SqlSession共享的,作用于是mapper配置文件中同一个namespace,不同的SqlSession两次执行相同namespace下的sql语句且参数如果也一样则最终执行的sql语句是相同的。每次查询都会先看看缓存中是否有对应查询结果,如果有就从缓存拿,如果没有就执行sql语句从数据库中读取,从而提高查询效率。Mybatis默认开启的是一级缓存,所以二级缓存需要自己手动开启。
application.yml
开启二级缓存
mybatis:
mapper-locations: classpath:com/baizhi/mapper/*.xml
executor-type: batch
type-aliases-package: com.baizhi.entities
#开启二级缓存
configuration:
cache-enabled: true
配置redis
#redis配置
redis:
host: 192.168.192.19
port: 6379
timeout: 5s
lettuce:
shutdown-timeout: 100ms
pool:
max-active: 8
max-idle: 8
max-wait: 10ms
min-idle: 1
pom.xml
添加redis依赖
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-pool2
添加redisTemplate配置Bean
//redisTemplate
@Bean
public RedisTemplate
实现ApplicationContextAware
【Springboot+Mybatis+redis实现二级缓存】该接?为标记接?,Spring??在初始化的时,会?动注?applicationContext
@Component
public class SpringContextHolderimplements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
//实现ApplicationContextAware接口的context注入函数, 将其存入静态变量
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}//从静态变量ApplicationContext中取得Bean
public static Object getBeanByName(String name){
Object bean = applicationContext.getBean(name);
return bean;
}
}
自定义MyBatisCache实现Cache
//自定义缓存
@Slf4j
public class MyCache implements Cache {
private final String id;
//redis缓存失效时间
private Long timeout = 300L;
private RedisTemplate redisTemplate;
public MyCache(String id){
this.id = id;
}// 读写锁
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
@Override
public String getId() {
return id;
}@Override
//加入缓存,第一次查询
public void putObject(Object key, Object value) {
log.info("====加入缓存key:"+key+",value:"+ value +",id:"+id+",第一次查询数据库=======");
redisTemplate = getRedisTemplate();
ValueOperations opsForValue = https://www.it610.com/article/redisTemplate.opsForValue();
opsForValue.set(key,value,timeout, TimeUnit.MINUTES);
}@Override
//查询首先查看缓存
public Object getObject(Object key) {
log.info("====查询前首先查看缓存key:"+key+"=id:"+id+"======");
redisTemplate = getRedisTemplate();
ValueOperations opsForValue = https://www.it610.com/article/redisTemplate.opsForValue();
return opsForValue.get(key);
}@Override
public Object removeObject(Object key) {
log.info("====数据库写操作,删除当前缓存key:"+key+"=======");
redisTemplate = getRedisTemplate();
ValueOperations opsForValue = https://www.it610.com/article/redisTemplate.opsForValue();
Object value = opsForValue.get(key);
redisTemplate.delete(key);
return value;
}@Override
//一旦修改了数据库删除缓存
public void clear() {
log.info("====清除所有缓存id:"+id+"=======");
redisTemplate = getRedisTemplate();
redisTemplate.execute((RedisConnection connection) ->{
connection.flushAll();
return null;
});
}@Override
public int getSize() {
return 0;
}@Override
public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}public void setTimeout(Long timeout){
this.timeout = timeout;
}private RedisTemplate getRedisTemplate() {
if (redisTemplate == null) {
redisTemplate = (RedisTemplate) SpringContextHolder.getBeanByName("redisTemplate");
}
return redisTemplate;
}
}
Mapper.xml
对于有不需要用到二级缓存的语句可以在标签内写userCache=“false”,默认为true开启缓存。
select from t_user
${column} like "%"#{value}"%"
limit #{pageNow},#{pageSize}
(select 默认useCache为true:使用缓存,flushCache为false:不清空缓存)
(insert、update、delete 默认flushCache为true:清空缓存)
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 人脸识别|【人脸识别系列】| 实现自动化妆
- paddle|动手从头实现LSTM
- pytorch|使用pytorch从头实现多层LSTM