八股文面经之Mybatis笔记(下)

简介: 八股文面经之Mybatis笔记(下)

聊聊MyBatis内部的缓存设计



每当我们使用 MyBatis 开启一次和数据库的会话,MyBatis 会创建出一个 SqlSession 对象表示一次数据库会话。 在对数据库的一次会话中,我们有可能会反复地执行完全相同的查询语句,如果不采取一些措施的话,每一次查询都会查询一次数据库,而我们在极短的时间内做了完全相同的查询,那么它们的结果极有可能完全相同,由于查询一次数据库的代价很大,这有可能造成很大的资源浪费。


为了解决这一问题,减少资源的浪费,MyBatis 会在表示会话的 SqlSession 对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候,如果判断先前有个完全一样的查询,会直接从缓存中直接将结果取出,返回给用户,不需要再进行一次数据库查询了。


网络异常,图片无法展示
|


mybatis的内部的cache目录下包含有多种缓存的设计,全部都存放在了一个包内部,主要是对cache接口进行了多实现。


网络异常,图片无法展示
|


一级缓存


一级缓存是和sqlsession做绑定关联的一种存储设计,当首次查询出来的数据会被存储到一个hashmap中,而对应的cacheKey这块可以在源代码org.apache.ibatis.executor.BaseExecutor#createCacheKey里看到。


网络异常,图片无法展示
|


如果需要查看缓存的更多细节部分,可以debug模式切换到org.apache.ibatis.cache.impl.PerpetualCache里面进行查看。


网络异常,图片无法展示
|


内部包含了一个HashMap集合用于存储缓存数据。而所谓的清除缓存就是将这个hashmap执行clear操作。


网络异常,图片无法展示
|


缓存如何实现唯一值?


通过类的函数id+包名实现唯一值图片:


网络异常,图片无法展示
|


内部对于缓存还会区分环境类型:


网络异常,图片无法展示
|


这里的环境id正好对应了配置文件中所填写的id:


网络异常,图片无法展示
|


为什么一级缓存也叫查询缓存


因为查询出来的数据会放到一个map中,一旦出现写操作,缓存就会失效。

什么时候一级缓存会失效


一旦涉及到对应的update操作,就会清理缓存。


源代码如下所示:


@Override
public int update(MappedStatement ms, Object parameter) throws SQLException {
  ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
  if (closed) {
    throw new ExecutorException("Executor was closed.");
  }
  clearLocalCache();
  return doUpdate(ms, parameter);
}
复制代码


框架内部是如何识别该清理哪些缓存?


由于按照包名+类名+id的方式构建cache的key,所以没法识别出该清理哪个缓存,因此一旦进行更新操作的时候是直接将整个map进行清理。


网络异常,图片无法展示
|


网络异常,图片无法展示
|


网络异常,图片无法展示
|


网络异常,图片无法展示
|


一级缓存和sqlsession之间的关系


一个sqlsession会有一个自己专属的map用作一级缓存,不同sqlsession之间的缓存不会共享。


多数据源的情况下会连接不同的sqlsessionfactory,不同的sqlsessionfactory则对应不同的sqlsession,所以一级缓存不同,因此查询和更新的时候不会互相影响。


可以手动清理缓存吗?


可以通过sqlSession.clearCache();操作实现


如何判断两次查询是同一个查询:


按照cachekey的构建机制判断:

网络异常,图片无法展示
|


缓存的key是由好几个参数构建出来的:


  • hashcode
  • 查询的条数范围:如果是selectall系列,就是0-2147483647(21亿左右)
  • sql语句
  • enviorment的配置id


二级缓存


框架的内部默认是没有开启二级缓存的,需要开发人员手动开启。二级缓存是根据sqlsession进行识别的,同一个mapper在不同的sqlsession中会共享缓存。


代码案例:

需要执行commit操作才会写入到二级缓存中


网络异常,图片无法展示
|


同时在xml配置里需要额外配置:


mybatis-config.xml文件中:


网络异常,图片无法展示
|


对应到mapper文件中配置:


网络异常,图片无法展示
|


mybatis中还可以配置userCache和flushCache等配置项,userCache是用来设置是否禁用二级缓存的,在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

目录
相关文章
|
6月前
|
Java 数据库连接 数据库
Mybatis逆向工程笔记小结
Mybatis逆向工程笔记小结
|
2月前
|
SQL Java 数据库连接
【Java笔记+踩坑】MyBatisPlus基础
MyBatisPlus简介、标准数据层开发CRUD、业务层继承IService、ServiceImpl、条件查询、LambdaQueryWrapper、id生成策略、逻辑删除、乐观锁@Version、代码生成器、ActiveRecord
【Java笔记+踩坑】MyBatisPlus基础
|
2月前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
6月前
|
SQL Java 关系型数据库
MyBatis-Plus全套笔记三
MyBatis-Plus全套笔记三
|
6月前
|
SQL Java 数据库连接
MyBatis-Plus全套笔记二
MyBatis-Plus全套笔记二
|
6月前
|
Java 关系型数据库 数据库连接
MyBatis-Plus全套笔记一
MyBatis-Plus全套笔记一
132 1
|
SQL Java 数据库连接
[推荐] MyBatis框架初学笔记-为之后拾遗
[推荐] MyBatis框架初学笔记-为之后拾遗
58 0
|
SQL 存储 缓存
MyBatis 学习心得笔记
MyBatis 学习心得笔记
95 0