关键词:
文章目录
编程不良人Redis链接
Redis面经属实有点懵,回头补一下
1、二级缓存
作缓存的对象类型需要实现序列化
1.1、cache使用
在dao层对应的mapper配置文件中使用cache标签即可开启二级缓存
<cache/>
缓存是key-value形式,key可以看作select语句(key还包含其他信息’)
开启后,查询语句首先去通过select查询本地缓存,
- 若发现对应select命中缓存则直接返回结果
- 若没发现则请求数据库后返回结果会被添加到本地缓存,下次查询发现是同一条语句就会直接返回,不需要请求数据库,大大增加了查询效率
1.2、原理
Mybatis开启Cache后会默认使用实现了Cache接口的PerpetualCache类做缓存操作
也可以通过指定type使用不同的Cache子类做二级缓存
<cache type=""/>
public class PerpetualCache implements Cache
private final String id;
private final Map<Object, Object> cache = new HashMap();
public PerpetualCache(String id)
this.id = id;
public String getId()
return this.id;
public int getSize()
return this.cache.size();
public void putObject(Object key, Object value)
this.cache.put(key, value);
public Object getObject(Object key)
return this.cache.get(key);
public Object removeObject(Object key)
return this.cache.remove(key);
public void clear()
this.cache.clear();
public boolean equals(Object o)
if (this.getId() == null)
throw new CacheException("Cache instances require an ID.");
else if (this == o)
return true;
else if (!(o instanceof Cache))
return false;
else
Cache otherCache = (Cache)o;
return this.getId().equals(otherCache.getId());
public int hashCode()
if (this.getId() == null)
throw new CacheException("Cache instances require an ID.");
else
return this.getId().hashCode();
单体应用使用二级缓存绰绰有余,但是使用集群后,每个服务对应一个JVM,本地缓存是不共享的,所以就需要使用一个外界中间件提供共享缓存来实现二级缓存-Redis
2、Redis替代二级缓存
上面说到开启cache后使用Cache子类来进行缓存操作
所以我们通过实现Cache的自定义类
使用RedisTemplate来远程操作Redis进行缓存的操作,所有的缓存统一在redis上获取和添加
2.1、获取ApplicationContext
Cache实现类并没有添加到容器中,所以需要获取上下文来注入RedisTemplate
将类添加到容器的方式:@Service、@Controller、@Component等,里面可以随意使用自动注入
@Component
public class ApplicationContextUtils implements ApplicationContextAware
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
this.applicationContext=applicationContext;
public static Object getBean(String beanName)
return applicationContext.getBean(beanName);
2.2、自定义cache实现类
1、必须有常量字符串id
2、必须构造器赋予id(为mapper对应namespace,一个dao通常对应一个表的所有操作)
发现使用以id作key的hash类缓存很适合,同一个id下所有key为同一个dao的所有查询语句
hset namespace (select xx from) xxxx
hset namespace (select xx from) xxxx
清空缓存 清空id的对应缓存就将表更新后的对应的所有缓存清掉了
del namespace
缺点是级联查询的缓存有问题,通过cache-ref可解决(在下方)
3、put为添加缓存
4、get为获取缓存
5、当表更新后,就需要清空这张表对应的所有缓存,通过clear实现
public class RedisCache implements Cache
private final String id;
//id指定namespace
public RedisCache(String id)
System.out.println("id==========="+id);
this.id = id;
@Override
public String getId()
return this.id;
@Override
public void putObject(Object key, Object value)
System.out.println("key==="+key);
System.out.println("value==="+value);
getRedisTemplate().opsForHash().put(id,key.toString(),value);
@Override
public Object getObject(Object key)
System.out.println("key:"+key);
return getRedisTemplate().opsForHash().get(id,key.toString());
@Override
public Object removeObject(Object o)
return null;
@Override
public void clear()
getRedisTemplate().delete(id);
@Override
public int getSize()
return 0;
//方便获取redisTemplate
private RedisTemplate getRedisTemplate()
RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
redisTemplate.setKeySerializer(new StringRedisSerializer());//指定key的序列化类型
redisTemplate.setHashKeySerializer(new StringRedisSerializer());//指定hash类型的key序列化类型
return redisTemplate;
2.3、关联查询的缓存处理
关联查询的时候,会根据两个表进行查询
当其中一个表更新删除对应缓存后,另一张表的关联缓存可能还在就会导致一致性错误
所以通过缓存引用来解决关联查询的缓存问题
在关联查询的任意一方添加缓存引用即可
<cache-ref namespace="com.chime.redis_study.dao.UserDao"/>
当在对应mapper添加缓存引用后,之后该namespace的所有查询都会使用引用的缓存
如在EmpMapper里引用了EmpDao,EmpDao和UserDao共享UserDao的缓存空间,之后任意一表更新就会清空共享的所有缓存
3、缓存优化策略
3.1、对key进行优化
我们发现自动生成的key过长,可以通过MD5加密将其缩减为32位16进制字符串
MD5特点:
- 通过MD5加密后生成32位16进制字符串
- 不同内容文件经过加密,加密结果不一致(如何比较两文件内容不同?–通过MD5加密后比较加密串)
- 相同内容文件多次经过MD5加密结果一致
@Test
public void testMd5()
String key="-453465999:1075164090:com.chime.redis_study.dao.UserDao.findAll:0:2147483647:select id,name,age from user:SqlSessionFactoryBean";
String s = DigestUtils.md5DigestAsHex(key.getBytes());
System.out.println(s);
a22ac04c2dcd56aa81f82243f644e503
优化的Cache实现类(只需要修改与key关联的put、set就行)
public class RedisCache implements Cache
@Override
public void putObject(Object key, Object value)
getRedisTemplate().opsForHash().put(id,getKeyToMd5(key.toString()),value);
@Override
public Object getObject(Object key)
return getRedisTemplate().opsForHash().get(id,getKeyToMd5(key.toString()));
public String getKeyToMd5(String key)
return DigestUtils.md5DigestAsHex(key.getBytes());
推荐Redis做缓存时key长度过长使用MD5对key进行优化
redis-替代mybatis二级缓存(代码片段)
文章目录1、二级缓存1.1、cache使用1.2、原理2、Redis替代二级缓存2.1、获取ApplicationContext2.2、自定义cache实现类2.3、关联查询的缓存处理3、缓存优化策略3.1、对key进行优化编程不良人Redis链接Redis面经属实有点懵,回头补一下1... 查看详情
springboot集成redis配置mybatis二级缓存(代码片段)
目录写在前面源码获取一、MyBatis缓存机制1.1、一级缓存1.2、二级缓存二、集成Redis2.1、安装Redis2.2、项目引入Redis2.2.1、Maven依赖2.2.2、配置application.yml2.2.3、配置序列化规则三、配置二级缓存2.1、开启二级缓存2.2、自定义缓存类2.3... 查看详情
mybatis从入门到精通—mybatis缓存和二级缓存整合redis(代码片段)
⼀级缓存缓存验证在⼀个sqlSession中,对user表根据username进⾏两次查询,查看他们发出sql语句的情况@Testpublicvoidtest1()throwsIOExceptionInputStreamresourceAsStream=Resources.getResourceAsStream("sqlMapConfig.xml");SqlSessionFactorysqlSes 查看详情
mybatis(代码片段)
二级缓存为什么有了一级缓存后,还需要有二级缓存呢?二级缓存是应用级缓存,也使得它具有更多的存储方式(redis,内存),而一级缓存只能在内存中存储数据。并且二级缓存存储的是应用整个生... 查看详情
springboot多模块项目applicationcontext无法getbean,mybatisplus二级缓存与放弃mybatis(plus)的二级缓存(代码片段)
SpringBoot多模块项目ApplicationContext无法getBean,MybatisPlus二级缓存与放弃Mybatis(Plus)的二级缓存事情是这样发生的我想用redis实现mybatis-plus的二级缓存,用mybatis的方法(准备好cahce类,在mapper文件里面标记上c... 查看详情
使用redis做mybaties的二级缓存-mybatis二级缓存小心使用
Mybatis默认对二级缓存是关闭的,一级缓存默认开启;下面就说说为什么使用二级缓存需要注意: 二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到的数据就是错误的... 查看详情
mybatis一级缓存,mybatis二级缓存,mybatis缓存失效(代码片段)
Mybatis一级缓存,Mybatis二级缓存,Mybatis缓存失效 ================================©Copyright蕃薯耀 2021-06-24https://www.cnblogs.com/fanshuyao/ 一、SpringBoot整合Mybatis1、pom.xml引入依赖(基于SpringBoot:2.3.12.REL 查看详情
03.redis+ssm整合(mybatis二级缓存)
...了,这里不再做代码复制工作。这里主要是利用redis去做mybatis的二级缓存,mybaits映射文件中所有的select都会刷新已有缓存,如果不存在就会新建缓存,所有的insert,update操作都会更新缓存。redis的好处也显而易见,可以使系统的... 查看详情
使用redis做mybatis的二级缓存
使用Redis做MyBatis的二级缓存 通常为了减轻数据库的压力,我们会引入缓存。在Dao查询数据库之前,先去缓存中找是否有要找的数据,如果有则用缓存中的数据即可,就不用查询数据库了。如果没有才去数据库中查找。这样就能... 查看详情
mybatis系列目录--5.mybatis一级缓存和二级缓存(redis实现)
转载请注明出处哈:http://carlosfu.iteye.com/blog/22386620.相关知识:查询缓存:绝大数系统主要是读多写少。缓存作用:减轻数据库压力,提供访问速度。 1.一级缓存测试用例(1)默认开启,不需要有什么配置(2)示意图 (3)测... 查看详情
springboot+mybatis+redis实现二级缓存
对于查询比较多的项目可以考虑配置二级缓存,mybatis本身的二级缓存是缓存到本地,但是对于多个节点的项目来说,可能会出现数据不一致的问题,所以采用redis缓存,这样二级缓存的数据就可以缓存到内存,可实现多个节点项... 查看详情
mybatis缓存专题-一文彻底搞懂mybatis二级缓存(代码片段)
...属性3.1.type3.2.eviction3.3.flushInterval3.4.size3.5readOnly3.6blocking4.MyBatis的缓存机制整体设计以及二级缓存的工作模式5.使用二级缓存,必须要具备的条件6.一级缓存 查看详情
mybatis缓存机制(代码片段)
...介绍2.一级缓存和二级缓存二、一级缓存三、二级缓存3.1mybatis自带的二级缓存3.1.1代码测试二级缓存3.1.2查询结果存入二级缓存的时机3.1.3二级缓存相关配置四、整合EHCache4.1EHCache简介4.2整合操作五、缓存基本原理5.1Cache接口5.2Perpe... 查看详情
mybatis集成redis作为二级缓存
mybatis默认开启了二级缓存功能,在mybatis主配置文件中,将cacheEnabled设置成false,则会关闭二级缓存功能<settings><!--二级缓存默认开启,false关闭--><settingname="cacheEnabled"value="false"/><!--mybatis日志打印到控制台--><set... 查看详情
mybatis二级缓存详解(代码片段)
1 二级缓存简介二级缓存是在多个SqlSession在同一个Mapper文件中共享的缓存,它是Mapper级别的,其作用域是Mapper文件中的namespace,默认是不开启的。看如下图: 整个流程是这样的(不考虑第三方缓存库):当开启二级缓存... 查看详情
mybatis一级缓存与二级缓存的区别你知道吗(代码片段)
前言Java面试经常问到Mybatis一级缓存和二级缓存,今天就给大家重点详解Mybatis一级缓存和二级缓存原理与区别。Mybatis缓存缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存可以避免频繁与数据库... 查看详情
mybatis一级缓存与二级缓存的区别你知道吗(代码片段)
前言Java面试经常问到Mybatis一级缓存和二级缓存,今天就给大家重点详解Mybatis一级缓存和二级缓存原理与区别。Mybatis缓存缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存可以避免频繁与数据库... 查看详情
使用redis作为mybatis的二级缓存
本次介绍一下使用mybatis-redis项目作为mybatis的二级缓存在生产项目中的配置与应用。首先,在pom中添加一下依赖:<!-- mybatis cache --><dependency> <groupId>org.mybatis.caches</groupId>& 查看详情