媒介
主题是Mybatis一级和二级缓存的应用及源码阐明。但愿在本场chat竣事后,可以或许辅佐读者伴侣大白以下三点。
本次阐明中涉及到的代码和数据库表均放在Github上,地点: mybatis-cache-demo。
目次
为到达以上三个目标,本文凭据以下顺序展开。
Mybatis的基本观念
本章节会对Mybatis举办概略的先容,分为官方界说和焦点组件先容。
首先是Mybatis官方界说,如下所示。
MyBatis是支持定制化SQL、存储进程以及高级映射的优秀的耐久层框架。MyBatis制止了险些所有的JDBC代码和手动配置参数以及获取功效集。MyBatis可以对设置和原生Map利用简朴的XML或注解,将接口和Java 的POJOs(Plain Old Java Objects,普通的 Java工具)映射成数据库中的记录。
其次是Mybatis的几个焦点观念。
下图就是一个针对Student表操纵的接口文件StudentMapper,在StudentMapper中,我们可以若干要领,这个要领背后就是代表着要执行的Sql的意义。
凡是也可以把涉及多表查询的要领界说在StudentMapper中,假如查询的主体仍然是Student表的信息。也可以将涉及多表查询的语句单独抽出一个独立的接口文件。
在界说完接口文件后,我们会开拓一个Sql映射文件,主要由mapper元素和select|insert|update|delete元素组成,如下图所示。
mapper元素代表这个文件是一个映射文件,利用namespace和详细的映射接口绑定起来,namespace的值就是这个接口的全限定类名。select|insert|update|delete代表的是Sql语句,映射接口中界说的每一个要领也会和映射文件中的语句通过id的方法绑定起来,要领名就是语句的id,同时会界说语句的入参和出参,用于完成和Java工具之间的转换。
在Mybatis初始化的时候,每一个语句城市利用对应的MappedStatement代表,利用namespace+语句自己的id来代表这个语句。如下代码所示,利用mapper.StudentMapper.getStudentById代表其对应的Sql。
SELECT id,name,age FROM student WHERE id = #{id}
在Mybatis执行时,会进入对应接口的要领,通过类名加上要领名的组合生成id,找到需要的MappedStatement,交给执行器利用。 至此,Mybatis的基本观念先容完毕。
一级缓存
一级缓存先容
在系统代码的运行中,我们大概会在一个数据库会话中,执行多次查询条件完全沟通的Sql,鉴于日常应用的大部门场景都是读多写少,这反复的查询会带来必然的网络开销,同时select查询的量较量大的话,对数据库的机能是有较量大的影响的。
假如是Mysql数据库的话,在处事端和Jdbc端都开启预编译支持的话,可以在当地JVM端缓存Statement,可以在Mysql处事端直接执行Sql,省去编译Sql的步调,但也无法制止和数据库之间的反复交互。关于Jdbc和Mysql预编译缓存的工作,可以看我的这篇博客JDBC和Mysql那些事。
Mybatis提供了一级缓存的方案来优化在数据库会话间反复查询的问题。实现的方法是每一个SqlSession中都持有了本身的缓存,一种是SESSION级别,即在一个Mybatis会话中执行的所有语句,城市共享这一个缓存。一种是STATEMENT级别,可以领略为缓存只对当前执行的这一个statement有效。假如用一张图来代表一级查询的查询进程的话,可以用下图暗示。