MyBatis的缓存分析

一:MyBatis缓存简介

MyBatis支持声明式数据缓存(declarative data caching)。当一条SQL语句被标记为“可缓存”后,首次执行它时从数据库获取的所有数据会被存储在一段高速缓存中,今后执行这条语句时就会从高速缓存中读取结果,而不是再次命中数据库。MyBatis提供了默认下基于Java HashMap的缓存实现,以及用于与OSCache、Ehcache、Hazelcast和Memcached连接的默认连接器。MyBatis还提供API供其他缓存实现使用。

  MyBatis执行SQL语句之后,这条语句就是被缓存,以后再执行这条语句的时候,会直接从缓存中拿结果,而不是再次执行SQL,这就是所说的一级缓存。一级缓存的作用域scope是SqlSession。

一级缓存

 测试

同个session进行两次相同查询:

 1 @Test
 2 public void test() {
 3     SqlSession sqlSession = sqlSessionFactory.openSession();
 4     try {
 5         User user = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
 6         log.debug(user);
 7         User user2 = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
 8         log.debug(user2);
 9     } finally {
10         sqlSession.close();
11     }
12 }
test

MyBatis只进行1次数据库查询:

1 ==>  Preparing: select * from USERS WHERE ID = ? 
2 ==> Parameters: 1(Integer)
3 <==      Total: 1
4 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
5 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
结果

同个session进行两次不同的查询:

 1 @Test
 2 public void test() {
 3     SqlSession sqlSession = sqlSessionFactory.openSession();
 4     try {
 5         User user = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
 6         log.debug(user);
 7         User user2 = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 2);
 8         log.debug(user2);
 9     } finally {
10         sqlSession.close();
11     }
12 }
test

MyBatis进行两次数据库查询:

1 ==>  Preparing: select * from USERS WHERE ID = ? 
2 ==> Parameters: 1(Integer)
3 <==      Total: 1
4 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
5 ==>  Preparing: select * from USERS WHERE ID = ? 
6 ==> Parameters: 2(Integer)
7 <==      Total: 1
8 User{id=2, name='FFF', age=50, birthday=Sat Dec 06 17:12:01 CST 2017}
结果

不同session,进行相同查询:

 1 @Test
 2 public void test() {
 3     SqlSession sqlSession = sqlSessionFactory.openSession();
 4     SqlSession sqlSession2 = sqlSessionFactory.openSession();
 5     try {
 6         User user = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
 7         log.debug(user);
 8         User user2 = (User)sqlSession2.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
 9         log.debug(user2);
10     } finally {
11         sqlSession.close();
12         sqlSession2.close();
13     }
14 }
test

MyBatis进行了两次数据库查询:

1 ==>  Preparing: select * from USERS WHERE ID = ? 
2 ==> Parameters: 1(Integer)
3 <==      Total: 1
4 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
5 ==>  Preparing: select * from USERS WHERE ID = ? 
6 ==> Parameters: 1(Integer)
7 <==      Total: 1
8 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
结果

同个session,查询之后更新数据,再次查询相同的语句:

 1 @Test
 2 public void test() {
 3     SqlSession sqlSession = sqlSessionFactory.openSession();
 4     try {
 5         User user = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
 6         log.debug(user);
 7         user.setAge(100);
 8         sqlSession.update("org.format.mybatis.cache.UserMapper.update", user);
 9         User user2 = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
10         log.debug(user2);
11         sqlSession.commit();
12     } finally {
13         sqlSession.close();
14     }
15 }
test

更新操作之后缓存会被清除:

 1 ==>  Preparing: select * from USERS WHERE ID = ? 
 2 ==> Parameters: 1(Integer)
 3 <==      Total: 1
 4 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
 5 ==>  Preparing: update USERS SET NAME = ? , AGE = ? , BIRTHDAY = ? where ID = ? 
 6 ==> Parameters: format(String), 23(Integer), 2017-10-12 23:20:13.0(Timestamp), 1(Integer)
 7 <==    Updates: 1
 8 ==>  Preparing: select * from USERS WHERE ID = ? 
 9 ==> Parameters: 1(Integer)
10 <==      Total: 1
11 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
结果

很明显,结果验证了一级缓存的概念,在同个SqlSession中,查询语句相同的sql会被缓存,但是一旦执行新增或更新或删除操作,缓存就会被清除

原文地址:https://www.cnblogs.com/nullering/p/9310036.html