赞
踩
mybatis提供查询缓存,用于减轻数据库的压力,提高数据库的性能
Mybatis的一级缓存是SQLSession级别的缓存、mybatis默认是开启一级缓存的。在SQLSession实例对象下存在一个数据结构(HashMap),用户进行存储缓存数据,不同的SQLSession有各自的缓存数据区域,它们之间互不影响。
用法:
- 在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内
-
- 存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该
-
- sqlSession中的一级缓存也就不存在了。当数据库发生变更操作(insert、update、delete)操作时,会将缓
-
- 存数据删除。这样做的目标是避免缓存数据和数据库数据不一致,读取脏数据
-
实际操作:
- SqlSession sqlSession = sqlSessionFactory.openSession();
- UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
-
- System.out.println("第一次开始");
- User user = userMapper.getUserByID(1);
- System.out.println(user.toString());
- System.out.println("第一次结束");
-
- System.out.println("第二次开始");
- User user1 = userMapper.getUserByID(1);
- System.out.println(user.toString());
- System.out.println("第二次结束");
- 第一次开始
- 2019-06-16-17:28:54,299 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
- 2019-06-16-17:28:54,828 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 182738614.
- 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]
- 2019-06-16-17:28:54,833 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
- 2019-06-16-17:28:54,951 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
- 2019-06-16-17:28:54,986 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
- User{id=1, name='wj', sex='19', address='西安'}
- 第一次结束
- 第二次开始
- User{id=1, name='wj', sex='19', address='西安'}
- 第二次结束
从结果可以看出,第二次查询的时候并没有去数据库里面进行查询。
- SqlSession sqlSession = sqlSessionFactory.openSession();
- UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
-
- System.out.println("第一次开始");
- User user = userMapper.getUserByID(1);
- System.out.println(user.toString());
- System.out.println("第一次结束");
-
- User user2 = new User(6,"w","男","陕西");
- userMapper.InsertUser(user2);
-
- System.out.println("第二次开始");
- User user1 = userMapper.getUserByID(1);
- System.out.println(user1.toString());
- System.out.println("第二次结束");
- 第一次开始
- 2019-06-16-17:32:12,109 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
- 2019-06-16-17:32:12,629 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 182738614.
- 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]
- 2019-06-16-17:32:12,633 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
- 2019-06-16-17:32:12,748 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
- 2019-06-16-17:32:12,787 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
- User{id=1, name='wj', sex='19', address='西安'}
- 第一次结束
- 2019-06-16-17:32:12,789 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - ==> Preparing: insert into user (id, name, sex, address ) values ( ?,?, ?, ? )
- 2019-06-16-17:32:12,791 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - ==> Parameters: 6(Integer), w(String), 男(String), 陕西(String)
- 2019-06-16-17:32:12,792 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - <== Updates: 1
- 第二次开始
- 2019-06-16-17:32:12,793 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
- 2019-06-16-17:32:12,793 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
- 2019-06-16-17:32:12,795 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
- User{id=1, name='wj', sex='19', address='西安'}
- 第二次结束
我们看到了进行插入操作后,第二次查询只能去数据库进行查询了。
二级缓存是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后,才能把第一次查询的结果提交,才会写入缓存里面
在全局配置中配置开启二级缓存
- <settings>
- <!--开启二级缓存-->
- <setting name="cacheEnabled" value="true"/>
- </settings>
在mapper.xml文件中打开缓存
- <cache eviction="LRU" flushInterval="1000" size="100"></cache>
- eviction表示缓存淘汰策略
- LRU:最近最少使用
- SqlSession sqlSession1 = sqlSessionFactory.openSession();
- SqlSession sqlSession = sqlSessionFactory.openSession();
- SqlSession sqlSession2 = sqlSessionFactory.openSession();
- UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
- UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
- UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
-
- System.out.println("第一次开始");
- User user = userMapper.getUserByID(1);
- System.out.println(user.toString());
- System.out.println("第一次结束");
- sqlSession.close();
-
-
- System.out.println("第二次开始");
- User user1 = userMapper1.getUserByID(1);
- System.out.println(user1.toString());
- System.out.println("第二 次结束");
- 第一次开始
- 2019-06-16-17:40:56,362 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.0
- 2019-06-16-17:40:56,379 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
- 2019-06-16-17:40:56,978 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 87765719.
- 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]
- 2019-06-16-17:40:56,983 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
- 2019-06-16-17:40:57,038 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
- 2019-06-16-17:40:57,119 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
- User{id=1, name='wj', sex='19', address='西安'}
- 第一次结束
- 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]
- 2019-06-16-17:40:57,146 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
- 2019-06-16-17:40:57,147 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Returned connection 87765719 to pool.
- 第二次开始
- 2019-06-16-17:40:57,266 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.5
- User{id=1, name='wj', sex='19', address='西安'}
- 第二 次结束
此时已经命中缓存了
- SqlSession sqlSession1 = sqlSessionFactory.openSession();
- SqlSession sqlSession = sqlSessionFactory.openSession();
- SqlSession sqlSession2 = sqlSessionFactory.openSession();
- UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
- UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
- UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
-
- System.out.println("第一次开始");
- User user = userMapper.getUserByID(1);
- System.out.println(user.toString());
- System.out.println("第一次结束");
- sqlSession.close();
-
-
- System.out.println("第二次开始");
- User user1 = userMapper1.getUserByID(1);
- System.out.println(user1.toString());
- System.out.println("第二 次结束");
-
- User user2 = new User(10,"w","男","陕西");
- userMapper1.InsertUser(user2);
- sqlSession1.commit();
-
-
- System.out.println("第三次开始");
- User user3 = userMapper2.getUserByID(1);
- System.out.println(user3.toString());
- System.out.println("第三 次结束");
- 第一次开始
- 2019-06-16-17:46:34,598 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.0
- 2019-06-16-17:46:34,611 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
- 2019-06-16-17:46:35,086 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 87765719.
- 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]
- 2019-06-16-17:46:35,091 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
- 2019-06-16-17:46:35,154 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
- 2019-06-16-17:46:35,211 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
- User{id=1, name='wj', sex='19', address='西安'}
- 第一次结束
- 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]
- 2019-06-16-17:46:35,235 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
- 2019-06-16-17:46:35,236 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Returned connection 87765719 to pool.
- 第二次开始
- 2019-06-16-17:46:35,358 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.5
- User{id=1, name='wj', sex='19', address='西安'}
- 第二 次结束
- 2019-06-16-17:46:35,359 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
- 2019-06-16-17:46:35,359 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Checked out connection 87765719 from pool.
- 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]
- 2019-06-16-17:46:35,360 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - ==> Preparing: insert into user (id, name, sex, address ) values ( ?,?, ?, ? )
- 2019-06-16-17:46:35,361 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - ==> Parameters: 10(Integer), w(String), 男(String), 陕西(String)
- 2019-06-16-17:46:35,362 [main] [com.wj.dao.UserMapper.InsertUser] [DEBUG] - <== Updates: 1
- 2019-06-16-17:46:35,362 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@53b32d7]
- 第三次开始
- 2019-06-16-17:46:35,408 [main] [com.wj.dao.UserMapper] [DEBUG] - Cache Hit Ratio [com.wj.dao.UserMapper]: 0.3333333333333333
- 2019-06-16-17:46:35,408 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction] [DEBUG] - Opening JDBC Connection
- 2019-06-16-17:46:35,428 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource] [DEBUG] - Created connection 1033490990.
- 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]
- 2019-06-16-17:46:35,430 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Preparing: select * from user where id = ?
- 2019-06-16-17:46:35,430 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - ==> Parameters: 1(Integer)
- 2019-06-16-17:46:35,432 [main] [com.wj.dao.UserMapper.getUserByID] [DEBUG] - <== Total: 1
- User{id=1, name='wj', sex='19', address='西安'}
- 第三 次结束
可以看到第三次就需要去数据库中查找了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。