一级缓存

2018-07-31  本文已影响8人  神豪VS勇士赢

一级缓存是SqlSession级别的缓存。(默认支持)
缓存的本质:减少查询DB的次数,提升性能。解决高并发的问题。

同样的Session,同样的请求,多次请求:
第一次从DB获取记录后,缓存SqlSession同样有了对应的记录。

图解:


image.png

注意:
sqlSession去执行commit操作(插入、更新、删除),清空一级缓存。
执行更新不提交也会清空一级缓存,但更新记录不进DB。
需要加入日志包和日志属性文件打印SQL

缓存和数据库中的内容需要一致?
SqlSession修改记录,不提交事务,现在SqlSession中的内容和DB中内容是否一致?清空一级缓存的本质,就是为了让缓存和DB的数据一致。再次请求记录的时候从DB找记录,这样缓存和DB一致。

编写测试类 观察以及缓存 :

测试一:
sqlSession 为同一个的时候:

@Test
public void testOneCache(){
SqlSession sqlSession = SqlSessionFactoryUtilSingleL.getSqlSession();
BookInfoMapper mapper = sqlSession.getMapper(BookInfoMapper.class);
BookInfo bookInfo = mapper.selectByPrimaryKey(1l);
Log.debug(bookInfo);
BookInfoMapper mapper1 = sqlSession.getMapper(BookInfoMapper.class);
BookInfo bookInfo1 = mapper.selectByPrimaryKey(1l);
Log.debug(bookInfo1);
}
输出结果如下:

image.png

得出结论 :当使用同一个sqlSession 并且第二次查询的信息为第一次查询过的信息 第二次查询是直接从以及缓存中查的数据输出。

测试二:
当我们使用不同的SqlSession 查询 同一条数据信息

@Test
public void testOneChacheDiffSqlSession(){
SqlSession sqlSession = SqlSessionFactoryUtilSingleL.getSqlSession();
BookInfoMapper mapper = sqlSession.getMapper(BookInfoMapper.class);
BookInfo bookInfo = mapper.selectByPrimaryKey(1l);
Log.debug(bookInfo);
SqlSession sqlSession1 = SqlSessionFactoryUtilSingleL.getSqlSession();
BookInfoMapper mapper1 = sqlSession1.getMapper(BookInfoMapper.class);
BookInfo bookInfo1 = mapper1.selectByPrimaryKey(1l);
Log.debug(bookInfo1);
}
输出结果如下所示:


image.png

得出结论 :当使用不同的SqlSession查询同一条数据信息的时候 分别从数据库中查询数据信息,不会从一级缓存中 取信息。

测试三:
我们在使用同一个sqlSession 查询数据信息的中间 加入了一个 操作数据库的操作 ,但是并没有commit

@Test
public void testOneCacheAfterCommit(){
SqlSession sqlSession = SqlSessionFactoryUtilSingleL.getSqlSession();
BookInfoMapper mapper = sqlSession.getMapper(BookInfoMapper.class);
BookInfo bookInfo = mapper.selectByPrimaryKey(1l);
Log.debug(bookInfo);

    bookInfo.setBookName("java钢贴贴");
    mapper.updateByPrimaryKey(bookInfo);

    BookInfo bookInfo1 = mapper.selectByPrimaryKey(1l);
    Log.debug(bookInfo1);
}

输出结果如下:


image.png

得出结论 :

第一次查询数据信息   在DB 中查询数据 ,接下来 更新数据 ,但是更新数据 并没有提交,

这个时候使用之前查询的sqlSession 这个时候查询出的数据为 一级缓存中的数据。

测试四:

我们先使用 SqlSession查询第一次数据 , 同事使用第一个SqlSession 进行数据更新 ,但是此时并没有提交(commit),这个时候使用第二个 sqlSession 进行查询 , 接下来 使用 第一个sqlSession 进行查询数据信息 。

@Test
public void  testOneCacheAfterCommit(){
    SqlSession sqlSession = SqlSessionFactoryUtilSingleL.getSqlSession();
    BookInfoMapper mapper = sqlSession.getMapper(BookInfoMapper.class);
    BookInfo bookInfo = mapper.selectByPrimaryKey(1l);
    Log.debug(bookInfo);

    bookInfo.setBookName("java钢贴贴");
    mapper.updateByPrimaryKey(bookInfo);
    SqlSession sqlSession1 = SqlSessionFactoryUtilSingleL.getSqlSession();
    BookInfoMapper mapper1 = sqlSession1.getMapper(BookInfoMapper.class);
    BookInfo bookInfo1 = mapper1.selectByPrimaryKey(1l);
    Log.debug(bookInfo1);
    BookInfo bookInfo2 = mapper.selectByPrimaryKey(1l);
    Log.debug(bookInfo2);
}

输出结果如下所示:


image.png

得出结论 :
第一个的sqlSession 更改数据 ,但是并没有修改数据 , 所以第二个sqlSession 查询数据的时候
重新查询DB ,这时候 输出结果还是 第一次的查询数据 , 再次使用第一个sqlSession 查询数据的时候,
查询的是 第一个 sqlSession的一级缓存。

测试五 :
仅仅修改一行代码 ,使用第一个 sqlSession 更新数据 ,之后提交(commit ) 其他代码一模一样。

@Test
public void testOneCacheAfterCommit(){
SqlSession sqlSession = SqlSessionFactoryUtilSingleL.getSqlSession();
BookInfoMapper mapper = sqlSession.getMapper(BookInfoMapper.class);
BookInfo bookInfo = mapper.selectByPrimaryKey(1l);
Log.debug(bookInfo);
bookInfo.setBookName("java钢贴贴");
mapper.updateByPrimaryKey(bookInfo);
sqlSession.commit();
SqlSession sqlSession1 = SqlSessionFactoryUtilSingleL.getSqlSession();
BookInfoMapper mapper1 = sqlSession1.getMapper(BookInfoMapper.class);
BookInfo bookInfo1 = mapper1.selectByPrimaryKey(1l);
Log.debug(bookInfo1);
BookInfo bookInfo2 = mapper.selectByPrimaryKey(1l);
Log.debug(bookInfo2);
}

输出结果如下所示:


image.png

得出结果:
第一个sqlSession更新数据,并且提交(commit) ,第二个sqlSession 查询出来的数据是根据DB 查询 , 第一个sqlSession 再次查询数据信息的时候,是从新从DB 查询信息 ,而不是从以及缓存中查询,因为一级缓存 因为 (commit)之后 数据库被修改 所以一级缓存信息被删除 ,再次访问的时候 从DB 查询并输出 。

上一篇下一篇

猜你喜欢

热点阅读