15-一级缓存
Posted zuiren
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了15-一级缓存相关的知识,希望对你有一定的参考价值。
目录
一、Mybatis 中的缓存
1.什么是缓存
存在内存中的临时数据。
2.为什么使用缓存
减少与数据库交互次数,提高执行效率
3.什么样的数据能使用缓存,什么样的数据不能使用缓存
适用于缓存:
- 经常查询并且不经常改变。
- 数据的正确与否对最终结果影响不大的。
不适用于缓存:
- 经常改变的数据。
- 数据的正确与否对最终结果影响很大。
- 例如:商品的库存,银行的汇率,股市的牌价。
3.Mybatis 中的一级缓存和二级缓存
一级缓存:
- 它指的是 Mybatis 中 SqlSession 对象的缓存。
- 当我们执行查询之后,查询的结果会同时存入到 SqlSession 为我们提供一块区域中。
- 该区域的结构时一个 Map 。当我们再次查询同样的数据,mybatis 会先去 sqlsession 中查询是否有,有的话直接拿出来用。
- 当 SqlSession 对象消失时,mybatis 的一级缓存也就消失了。
二、一级缓存
一级缓存分析
一级缓存是 sqlsession 范围的缓,当调用 sqlsession 的修改、添加、删除、commit()、close()等方法时,就会清空一级缓存
1.一级缓存测试
Ⅰ测试类代码
/**
* 一级缓存
*/
@Test
public void testFirstLevelCache()
User user1=userDao.findById(1);
System.out.println(user1);
User user2=userDao.findById(1);
System.out.println(user2);
System.out.println(user1==user2);
Ⅱ输出结果
Opening JDBC Connection
[DEBUG] 2019-08-16 10:37:32,206 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:424)
Created connection 11902257.
[DEBUG] 2019-08-16 10:37:32,209 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: select *from user where id=?
[DEBUG] 2019-08-16 10:37:32,233 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 1(Integer)
[DEBUG] 2019-08-16 10:37:32,254 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
domain.User@19dc67c2
[DEBUG] 2019-08-16 10:37:32,254 method:org.apache.ibatis.transaction.jdbc.JdbcTransaction.close(JdbcTransaction.java:90)
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@b59d31]
[DEBUG] 2019-08-16 10:37:32,255 method:org.apache.ibatis.datasource.pooled.PooledDataSource.pushConnection(PooledDataSource.java:381)
Returned connection 11902257 to pool.
[DEBUG] 2019-08-16 10:37:32,255 method:org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:136)
Opening JDBC Connection
[DEBUG] 2019-08-16 10:37:32,255 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:416)
Checked out connection 11902257 from pool.
[DEBUG] 2019-08-16 10:37:32,256 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: select *from user where id=?
[DEBUG] 2019-08-16 10:37:32,256 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 1(Integer)
[DEBUG] 2019-08-16 10:37:32,257 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
domain.User@62bd765
false
可以看到上面的两个对象是同一个,并且返回是 true
而且他只发起了一次查询,第一次查询,第二次是从缓存中取出
如果 sqlsession 关闭则一级缓存关闭
2.关闭一级缓存
两种方法有所区别:
第一种方法是关闭 sqlsession ,重新建立一个
第二种是不关闭 sqlsession ,只清除缓存
Ⅰ第一种方法:
/**
* 关闭一级缓存
*/
@Test
public void testFirstLevelCache2()
User user1=userDao.findById(1);
System.out.println(user1);
sqlSession.close();
//再次获取 sqlsession
sqlSession= factory.openSession(true);
userDao=sqlSession.getMapper(IUserDao.class);
User user2=userDao.findById(1);
System.out.println(user2);
System.out.println(user1==user2);
输出日志:
Opening JDBC Connection
[DEBUG] 2019-08-16 10:37:32,255 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:416)
Checked out connection 11902257 from pool.
[DEBUG] 2019-08-16 10:37:32,256 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: select *from user where id=?
[DEBUG] 2019-08-16 10:37:32,256 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 1(Integer)
[DEBUG] 2019-08-16 10:37:32,257 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
domain.User@62bd765
false
Ⅱ第二种方法:
@Test
public void testFirstLevelCache2()
User user1=userDao.findById(1);
System.out.println(user1);
sqlSession.clearCache();
userDao=sqlSession.getMapper(IUserDao.class);
User user2=userDao.findById(1);
System.out.println(user2);
System.out.println(user1==user2);
输出日志:
Opening JDBC Connection
[DEBUG] 2019-08-16 10:41:08,333 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:424)
Created connection 11902257.
[DEBUG] 2019-08-16 10:41:08,336 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: select *from user where id=?
[DEBUG] 2019-08-16 10:41:08,365 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 1(Integer)
[DEBUG] 2019-08-16 10:41:08,386 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
domain.User@19dc67c2
[DEBUG] 2019-08-16 10:41:08,387 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: select *from user where id=?
[DEBUG] 2019-08-16 10:41:08,389 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 1(Integer)
[DEBUG] 2019-08-16 10:41:08,392 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
domain.User@62bd765
false
2.在两个相同查询中间进行增、删、改
一级缓存分析
一级缓存是 sqlsession 范围的缓,当调用 sqlsession 的修改、添加、删除、commit()、close()等方法时,就会清空一级缓存
Ⅰ改代码
/**
* 测试缓存的同步
*/
@Test
public void testClearCache()
//1.根据 id 查询用户
User user1=userDao.findById(1);
System.out.println(user1);
//2.跟新用户信息
user1.setUsername("update user");
user1.setAddress("北京市海淀区");
userDao.updateUser(user1);
User user2=userDao.findById(1);
System.out.println(user2);
System.out.println(user1==user2);
输出日志:
Opening JDBC Connection
[DEBUG] 2019-08-16 10:56:30,917 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:424)
Created connection 11902257.
[DEBUG] 2019-08-16 10:56:30,922 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: select *from user where id=?
[DEBUG] 2019-08-16 10:56:30,946 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 1(Integer)
[DEBUG] 2019-08-16 10:56:30,962 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
domain.User@19dc67c2
[DEBUG] 2019-08-16 10:56:30,964 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: update user set username=?,address=? where id=?
[DEBUG] 2019-08-16 10:56:30,964 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: update user(String), 北京市海淀区(String), 1(Integer)
[DEBUG] 2019-08-16 10:56:30,982 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Updates: 1
[DEBUG] 2019-08-16 10:56:30,983 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Preparing: select *from user where id=?
[DEBUG] 2019-08-16 10:56:30,983 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 1(Integer)
[DEBUG] 2019-08-16 10:56:30,984 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<== Total: 1
domain.User@78a2da20
false
以上是关于15-一级缓存的主要内容,如果未能解决你的问题,请参考以下文章