Mybatis缓存
官方文档地址
https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache
一级缓存
一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession, Mabits默认开启一级缓存。 在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。 当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。
对比下面两次查询的日志验证Mybatis的一级缓存
@Test
public void getStu() {
System.out.println(mapper.getById(3));
System.out.println(mapper.getById(3));
}
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: select * from student where id = ?;
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 3(Integer)
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
Student{id=3, name='yui', gender='男', favorites='[篮球, 足球]'}
Student{id=3, name='yui', gender='男', favorites='[篮球, 足球]'}
@Test
public void getStu() {
System.out.println(mapper.getById(3));
sqlSession.clearCache();
System.out.println(mapper.getById(3));
}
==> Preparing: select * from student where id = ?;
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 3(Integer)
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
Student{id=3, name='yui', gender='男', favorites='[篮球, 足球]'}
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: select * from student where id = ?;
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 3(Integer)
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
Student{id=3, name='yui', gender='男', favorites='[篮球, 足球]'}
二级缓存
二级缓存 二级缓存是mapper级别的,Mybatis默认是没有开启二级缓存的。 第一次调用mapper下的SQL去查询用户的信息,查询到的信息会存放代该mapper对应的二级缓存区域。 第二次调用namespace下的mapper映射文件中,相同的sql去查询用户信息,会去对应的二级缓存内取结果。
二级缓存配置
-
全局缓存开关
<settings> <!-- 全局缓存开关,默认是true --> <setting name="cacheEnabled" value="true"/> </settings>
-
各个*Mapper.xml默认不使用cache,开启的话加一行
<cache/>
即可 -
执行2. 后mapper文件中的所有方法都使用cache,如果其中有个别不需要缓存,可以使用usecahe属性关闭
<select id="getById" resultMap="StuMap" useCache="false"> select * from student where id = #{id}; </select>
-
如果readOnly为false(默认),此时要结果集对象是可序列化的
二级缓存开关日志对比
@Test
public void getStu2() {
System.out.println(mapper.getById(3));
sqlSession.close();
sqlSession = sqlSessionFactory.openSession();
mapper = sqlSession.getMapper(StudentMapper.class);
System.out.println(mapper.getById(3));
}
不开启
==> Preparing: select * from student where id = ?;
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 3(Integer)
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
Student{id=3, name='yui', gender='男', favorites='[篮球, 足球]'}
......
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@612fc6eb]
......
Opening JDBC Connection
......
==> Preparing: select * from student where id = ?;
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 3(Integer)
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
Student{id=3, name='yui', gender='男', favorites='[篮球, 足球]'}
开启
==> Preparing: select * from student where id = ?;
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 3(Integer)
[DEBUG] 2021-03-07 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
Student{id=3, name='yui', gender='男', favorites='[篮球, 足球]'}
[DEBUG] 2021-03-07 method:org.apache.ibatis.transaction.jdbc.JdbcTransaction.resetAutoCommit(JdbcTransaction.java:122)
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@612fc6eb]
[DEBUG] 2021-03-07 method:org.apache.ibatis.transaction.jdbc.JdbcTransaction.close(JdbcTransaction.java:90)
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@612fc6eb]
[DEBUG] 2021-03-07 method:org.apache.ibatis.datasource.pooled.PooledDataSource.pushConnection(PooledDataSource.java:381)
Returned connection 1630521067 to pool.
[DEBUG] 2021-03-07 method:org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:60)
Cache Hit Ratio [com.xgsama.mybatis.mapper.StudentMapper]: 0.5
Student{id=3, name='yui', gender='男', favorites='[篮球, 足球]'}
使用Redis做二级缓存
-
添加pom依赖
<dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-redis</artifactId> <version>1.0.0-beta2</version> </dependency>
-
在classpath下添加
redis.properties
文件host=localhost port=6379 password=xxx database=2
-
指定缓存类型
<cache eviction="LRU" type="org.mybatis.caches.redis.RedisCache"/>
官方文档
http://mybatis.org/redis-cache/index.html