当前位置:   article > 正文

MyBatis学习——缓存机制_sqlsession.getmapper有缓存作用吗

sqlsession.getmapper有缓存作用吗

mybatis提供查询缓存,用于减轻数据库的压力,提高数据库的性能

一级缓存

Mybatis的一级缓存是SQLSession级别的缓存、mybatis默认是开启一级缓存的。在SQLSession实例对象下存在一个数据结构(HashMap),用户进行存储缓存数据,不同的SQLSession有各自的缓存数据区域,它们之间互不影响。

用法:

  1. 在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内
  2. 存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该
  3. sqlSession中的一级缓存也就不存在了。当数据库发生变更操作(insert、update、delete)操作时,会将缓
  4. 存数据删除。这样做的目标是避免缓存数据和数据库数据不一致,读取脏数据

 

实际操作:

测试

  1. SqlSession sqlSession = sqlSessionFactory.openSession();
  2. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  3. System.out.println("第一次开始");
  4. User user = userMapper.getUserByID(1);
  5. System.out.println(user.toString());
  6. System.out.println("第一次结束");
  7. System.out.println("第二次开始");
  8. User user1 = userMapper.getUserByID(1);
  9. System.out.println(user.toString());
  10. System.out.println("第二次结束");

结果:

  1. 第一次开始
  2. 2019-06-16-17:28:54,299 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
  3. 2019-06-16-17:28:54,828 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 182738614.
  4. 2019-06-16-17:28:54,829 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@ae45eb6]
  5. 2019-06-16-17:28:54,833 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
  6. 2019-06-16-17:28:54,951 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
  7. 2019-06-16-17:28:54,986 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
  8. User{id=1, name='wj', sex='19', address='西安'}
  9. 第一次结束
  10. 第二次开始
  11. User{id=1, name='wj', sex='19', address='西安'}
  12. 第二次结束

从结果可以看出,第二次查询的时候并没有去数据库里面进行查询。

测试:进行了添加操作后

  1. SqlSession sqlSession = sqlSessionFactory.openSession();
  2. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  3. System.out.println("第一次开始");
  4. User user = userMapper.getUserByID(1);
  5. System.out.println(user.toString());
  6. System.out.println("第一次结束");
  7. User user2 = new User(6,"w","男","陕西");
  8. userMapper.InsertUser(user2);
  9. System.out.println("第二次开始");
  10. User user1 = userMapper.getUserByID(1);
  11. System.out.println(user1.toString());
  12. System.out.println("第二次结束");

结果:

  1. 第一次开始
  2. 2019-06-16-17:32:12,109 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
  3. 2019-06-16-17:32:12,629 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 182738614.
  4. 2019-06-16-17:32:12,630 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@ae45eb6]
  5. 2019-06-16-17:32:12,633 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
  6. 2019-06-16-17:32:12,748 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
  7. 2019-06-16-17:32:12,787 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
  8. User{id=1, name='wj', sex='19', address='西安'}
  9. 第一次结束
  10. 2019-06-16-17:32:12,789 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - ==> Preparing: insert into user (id, name, sex, address ) values ( ?,?, ?, ? )
  11. 2019-06-16-17:32:12,791 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - ==> Parameters: 6(Integer), w(String), 男(String), 陕西(String)
  12. 2019-06-16-17:32:12,792 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - <== Updates: 1
  13. 第二次开始
  14. 2019-06-16-17:32:12,793 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
  15. 2019-06-16-17:32:12,793 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
  16. 2019-06-16-17:32:12,795 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
  17. User{id=1, name='wj', sex='19', address='西安'}
  18. 第二次结束

我们看到了进行插入操作后,第二次查询只能去数据库进行查询了。

二级缓存

二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

当开一个会话时,一个SqlSession对象会使用一个Executor对象来完成会话操作,MyBatis的二级缓存机制的关键就是对这个Executor对象做文章 如果用户配置了cacheEnabled=true,那么MyBatis在为SqlSession对象创建Executor对象时,会对Executor对象加上一个装饰者:CachingExecutor,这时SqlSession使用CachingExecutor对象来完成操作请求 CachingExecutor对于查询请求,会先判断该查询请求在Application级别的二级缓存中是否有缓存结果

  • 如果有查询结果,则直接返回缓存结果

  • 如果缓存中没有,再交给真正的Executor对象来完成查询操作,之后CachingExecutor会将真正Executor返回的查询结果放置到缓存中,然后在返回给用户

mybatis二级缓存,必须sqlsession.close 或者commit后,才能把第一次查询的结果提交,才会写入缓存里面

 

在全局配置中配置开启二级缓存

  1. <settings>
  2. <!--开启二级缓存-->
  3. <setting name="cacheEnabled" value="true"/>
  4. </settings>

在mapper.xml文件中打开缓存

  1. <cache eviction="LRU" flushInterval="1000" size="100"></cache>
  2. eviction表示缓存淘汰策略
  3. LRU:最近最少使用

测试:

  1. SqlSession sqlSession1 = sqlSessionFactory.openSession();
  2. SqlSession sqlSession = sqlSessionFactory.openSession();
  3. SqlSession sqlSession2 = sqlSessionFactory.openSession();
  4. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  5. UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
  6. UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
  7. System.out.println("第一次开始");
  8. User user = userMapper.getUserByID(1);
  9. System.out.println(user.toString());
  10. System.out.println("第一次结束");
  11. sqlSession.close();
  12. System.out.println("第二次开始");
  13. User user1 = userMapper1.getUserByID(1);
  14. System.out.println(user1.toString());
  15. System.out.println("第二 次结束");

结果:

  1. 第一次开始
  2. 2019-06-16-17:40:56,362 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.0
  3. 2019-06-16-17:40:56,379 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
  4. 2019-06-16-17:40:56,978 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 87765719.
  5. 2019-06-16-17:40:56,978 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
  6. 2019-06-16-17:40:56,983 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
  7. 2019-06-16-17:40:57,038 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
  8. 2019-06-16-17:40:57,119 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
  9. User{id=1, name='wj', sex='19', address='西安'}
  10. 第一次结束
  11. 2019-06-16-17:40:57,146 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
  12. 2019-06-16-17:40:57,146 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
  13. 2019-06-16-17:40:57,147 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Returned connection 87765719 to pool.
  14. 第二次开始
  15. 2019-06-16-17:40:57,266 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.5
  16. User{id=1, name='wj', sex='19', address='西安'}
  17. 第二 次结束

此时已经命中缓存了

测试:进行添加操作

  1. SqlSession sqlSession1 = sqlSessionFactory.openSession();
  2. SqlSession sqlSession = sqlSessionFactory.openSession();
  3. SqlSession sqlSession2 = sqlSessionFactory.openSession();
  4. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  5. UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
  6. UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
  7. System.out.println("第一次开始");
  8. User user = userMapper.getUserByID(1);
  9. System.out.println(user.toString());
  10. System.out.println("第一次结束");
  11. sqlSession.close();
  12. System.out.println("第二次开始");
  13. User user1 = userMapper1.getUserByID(1);
  14. System.out.println(user1.toString());
  15. System.out.println("第二 次结束");
  16. User user2 = new User(10,"w","男","陕西");
  17. userMapper1.InsertUser(user2);
  18. sqlSession1.commit();
  19. System.out.println("第三次开始");
  20. User user3 = userMapper2.getUserByID(1);
  21. System.out.println(user3.toString());
  22. System.out.println("第三 次结束");

结果:

  1. 第一次开始
  2. 2019-06-16-17:46:34,598 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.0
  3. 2019-06-16-17:46:34,611 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
  4. 2019-06-16-17:46:35,086 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 87765719.
  5. 2019-06-16-17:46:35,087 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
  6. 2019-06-16-17:46:35,091 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
  7. 2019-06-16-17:46:35,154 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
  8. 2019-06-16-17:46:35,211 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
  9. User{id=1, name='wj', sex='19', address='西安'}
  10. 第一次结束
  11. 2019-06-16-17:46:35,235 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
  12. 2019-06-16-17:46:35,235 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
  13. 2019-06-16-17:46:35,236 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Returned connection 87765719 to pool.
  14. 第二次开始
  15. 2019-06-16-17:46:35,358 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.5
  16. User{id=1, name='wj', sex='19', address='西安'}
  17. 第二 次结束
  18. 2019-06-16-17:46:35,359 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
  19. 2019-06-16-17:46:35,359 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Checked out connection 87765719 from pool.
  20. 2019-06-16-17:46:35,359 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
  21. 2019-06-16-17:46:35,360 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - ==> Preparing: insert into user (id, name, sex, address ) values ( ?,?, ?, ? )
  22. 2019-06-16-17:46:35,361 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - ==> Parameters: 10(Integer), w(String), 男(String), 陕西(String)
  23. 2019-06-16-17:46:35,362 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - <== Updates: 1
  24. 2019-06-16-17:46:35,362 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
  25. 第三次开始
  26. 2019-06-16-17:46:35,408 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.3333333333333333
  27. 2019-06-16-17:46:35,408 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
  28. 2019-06-16-17:46:35,428 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 1033490990.
  29. 2019-06-16-17:46:35,429 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d99d22e]
  30. 2019-06-16-17:46:35,430 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
  31. 2019-06-16-17:46:35,430 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
  32. 2019-06-16-17:46:35,432 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
  33. User{id=1, name='wj', sex='19', address='西安'}
  34. 第三 次结束

可以看到第三次就需要去数据库中查找了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/159855
推荐阅读
相关标签
  

闽ICP备14008679号