1: mybatis的缓存
1.1 一级缓存
一级缓存默认是开启的,是会话级别的缓存,如果两次查询条件相同
的sql 中间没有增删改等操作,那么查询两次时,第二次会从一级缓存
中获取
代码示例如下
@Test
public void testFindStuById2(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = studentMapper.findById(1);
Student student2 = studentMapper.findById(1);
System.out.println(student);
System.out.println(student);
System.out.println(student==student2);
}
<setting name="localCacheScope" value="SESSION"/> 默认值
2024:01:26 23:21:18.718 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction -- Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@422e18]
2024:01:26 23:21:18.772 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Preparing: select * from t_student where id = ?
2024:01:26 23:21:18.797 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Parameters: 1(Integer)
2024:01:26 23:21:18.886 [main] DEBUG o.wl.mapper.StudentMapper.findById -- <== Total: 1
Student{id=1, name='haha', stuAddress='beijing', age=20, classList=null}
Student{id=1, name='haha', stuAddress='beijing', age=20, classList=null}
true
从日志可以看出,只进行了一次查询,两个对象是相同的
public void testFindStuById2(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = studentMapper.findById(1);
Student st= new Student();
st.setName("刘亦菲");
st.setAge(20);
st.setStuAddress("gz");
studentMapper.insertStudent(st);
Student student2 = studentMapper.findById(1);
System.out.println(student);
System.out.println(student2);
System.out.println(student==student2);
}
查看日志可以看出一级缓存被清空了,执行了两次查询
2024:01:26 23:27:57.617 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction -- Opening JDBC Connection
2024:01:26 23:27:58.323 [main] DEBUG o.a.i.d.pooled.PooledDataSource -- Created connection 4337176.
2024:01:26 23:27:58.324 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction -- Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@422e18]
2024:01:26 23:27:58.387 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Preparing: select * from t_student where id = ?
2024:01:26 23:27:58.421 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Parameters: 1(Integer)
2024:01:26 23:27:58.506 [main] DEBUG o.wl.mapper.StudentMapper.findById -- <== Total: 1
2024:01:26 23:27:58.507 [main] DEBUG o.w.m.StudentMapper.insertStudent -- ==> Preparing: insert into t_student(name,age,stu_address) values(?,?,?);
2024:01:26 23:27:58.519 [main] DEBUG o.w.m.StudentMapper.insertStudent -- ==> Parameters: 刘亦菲(String), 20(Integer), gz(String)
2024:01:26 23:27:58.660 [main] DEBUG o.w.m.StudentMapper.insertStudent -- <== Updates: 1
2024:01:26 23:27:58.665 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Preparing: select * from t_student where id = ?
2024:01:26 23:27:58.666 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Parameters: 1(Integer)
2024:01:26 23:27:58.733 [main] DEBUG o.wl.mapper.StudentMapper.findById -- <== Total: 1
Student{id=1, name='haha', stuAddress='beijing', age=20, classList=null}
Student{id=1, name='haha', stuAddress='beijing', age=20, classList=null}
false
1.2 二级缓存
<setting name="cacheEnabled" value="true"/> 开启二级缓存需要配置settings
并且在 mapper.xml中添加
<!--开启二级缓存-->
<cache />
@Test
public void testFindStuById3(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
SqlSession sqlSession2 = SqlSessionUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = studentMapper.findById(1);
System.out.println(student);
sqlSession.close(); // 清空一级缓存
StudentMapper studentMapper2 = sqlSession2.getMapper(StudentMapper.class);
Student student2 = studentMapper2.findById(1);
System.out.println(student2);
System.out.println(student==student2);
}
2024:01:26 23:43:20.785 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Preparing: select * from t_student where id = ?
2024:01:26 23:43:20.810 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Parameters: 1(Integer)
2024:01:26 23:43:20.898 [main] DEBUG o.wl.mapper.StudentMapper.findById -- <== Total: 1
Student{id=1, name='haha', stuAddress='beijing', age=20, classList=null}
2024:01:26 23:43:20.902 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction -- Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1e29ed9]
2024:01:26 23:43:20.956 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction -- Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1e29ed9]
2024:01:26 23:43:20.956 [main] DEBUG o.a.i.d.pooled.PooledDataSource -- Returned connection 31629017 to pool.
2024:01:26 23:43:20.958 [main] WARN o.a.ibatis.io.SerialFilterChecker -- As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
2024:01:26 23:43:20.962 [main] DEBUG org.wl.mapper.StudentMapper -- Cache Hit Ratio [org.wl.mapper.StudentMapper]: 0.5
Student{id=1, name='haha', stuAddress='beijing', age=20, classList=null}
1.3 第三方缓存
加入依赖
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.3</version>
</dependency>
public void testFindStuById3(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
SqlSession sqlSession2 = SqlSessionUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = studentMapper.findById(1);
System.out.println(student);
sqlSession.close(); // 清空一级缓存
StudentMapper studentMapper2 = sqlSession2.getMapper(StudentMapper.class);
Student student2 = studentMapper2.findById(1);
System.out.println(student2);
System.out.println(student==student2);
}
将mapper.xml 中的二级缓存的开关改为
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
在类路径下添加
ehcache.xml
<ehcache xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="java.io.tmpdir/ehcache"/>
<defaultCache
maxElementsInMemory='1000'
maxElementsOnDisk='10000000'
eternal='false'
overflowToDisk='false'
timeToIdleSeconds='120'
timeToLiveSeconds='120'
diskExpiryThreadIntervalSeconds='120'
memoryStoreEvictionPolicy='LRU'>
</defaultCache>
</ehcache>
执行查询之后 检查发现日志中使用了ehcache 的缓存了
2024:01:27 00:12:34.601 [main] DEBUG net.sf.ehcache.Cache -- No BootstrapCacheLoaderFactory class specified. Skipping...
2024:01:27 00:12:34.601 [main] DEBUG net.sf.ehcache.Cache -- CacheWriter factory not configured. Skipping...
2024:01:27 00:12:34.601 [main] DEBUG n.s.e.config.ConfigurationHelper -- No CacheExceptionHandlerFactory class specified. Skipping...
2024:01:27 00:12:34.667 [main] DEBUG net.sf.ehcache.store.MemoryStore -- Initialized net.sf.ehcache.store.NotifyingMemoryStore for org.wl.mapper.StudentMapper
2024:01:27 00:12:34.675 [main] DEBUG net.sf.ehcache.Cache -- Initialised cache: org.wl.mapper.StudentMapper
2024:01:27 00:12:34.675 [main] DEBUG n.s.e.config.ConfigurationHelper -- CacheDecoratorFactory not configured for defaultCache. Skipping for 'org.wl.mapper.StudentMapper'.
2024:01:27 00:12:34.770 [main] DEBUG org.wl.mapper.StudentMapper -- Cache Hit Ratio [org.wl.mapper.StudentMapper]: 0.0
2024:01:27 00:12:34.784 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction -- Opening JDBC Connection
2024:01:27 00:12:35.597 [main] DEBUG o.a.i.d.pooled.PooledDataSource -- Created connection 32929526.
2024:01:27 00:12:35.597 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction -- Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1f676f6]
2024:01:27 00:12:35.659 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Preparing: select * from t_student where id = ?
2024:01:27 00:12:35.683 [main] DEBUG o.wl.mapper.StudentMapper.findById -- ==> Parameters: 1(Integer)
2024:01:27 00:12:35.770 [main] DEBUG o.wl.mapper.StudentMapper.findById -- <== Total: 1
Student{id=1, name='haha', stuAddress='beijing', age=20, classList=null}
2024:01:27 00:12:35.770 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction -- Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1f676f6]
2024:01:27 00:12:35.834 [main] DEBUG o.a.i.t.jdbc.JdbcTransaction -- Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1f676f6]
2024:01:27 00:12:35.834 [main] DEBUG o.a.i.d.pooled.PooledDataSource -- Returned connection 32929526 to pool.
2024:01:27 00:12:35.834 [main] DEBUG org.wl.mapper.StudentMapper -- Cache Hit Ratio [org.wl.mapper.StudentMapper]: 0.5
Student{id=1, name='haha', stuAddress='beijing', age=20, classList=null}
true