mybatis一级,二级缓存。缓存带来的脏读问题
title
- 1. 關(guān)于緩存的介紹
- 2. 一級緩存,默認(rèn)開啟,session級別
- 3. 二級緩存,mapper 的namespace級別
1. 關(guān)于緩存的介紹
Mybatis一級緩存的作用域是同一個(gè)SqlSession,在同一個(gè)sqlSession中兩次執(zhí)行相同的sql語句,第一次執(zhí)行完
畢會將數(shù)據(jù)庫中查詢到的數(shù)據(jù)寫到緩存(內(nèi)存),第二次會從緩存中獲取數(shù)據(jù)將不再從數(shù)據(jù)庫查詢,從而提
高查詢效率。當(dāng)一個(gè)sqlSession結(jié)束后該sqlSession中的一級緩存也就不存在了。Mybatis默認(rèn)開啟一級緩存。
Mybatis二級緩存是多個(gè)SqlSession共享的,其作用域是mapper的同一個(gè)namespace,不同的sqlSession兩次執(zhí)行
相同namespace下的sql語句且向sql中傳遞參數(shù)也相同即最終執(zhí)行相同的sql語句,第一次執(zhí)行完畢會將數(shù)據(jù)庫
中查詢的數(shù)據(jù)寫到緩存(內(nèi)存),第二次會從緩存中獲取數(shù)據(jù)將不再從數(shù)據(jù)庫查詢,從而提高查詢效
率。Mybatis默認(rèn)沒有開啟二級緩存需要在setting全局參數(shù)中配置開啟二級緩存。
如果二級緩存沒有取到,再從一級緩存中找,如果一級緩存也沒有,從數(shù)據(jù)庫查詢。
2. 一級緩存,默認(rèn)開啟,session級別
一級緩存的清空:
1、關(guān)于一級緩存的清空 一級緩存區(qū)域是根據(jù)SqlSession為單位劃分的。 每次查詢會先從緩存區(qū)域找, 如果找不到從數(shù)據(jù)庫查詢,查詢 到數(shù)據(jù)將數(shù)據(jù)寫入緩存。 Mybatis內(nèi)部存儲緩存使用一個(gè)HashMap, Key為hashCode+sqlId+sql語句。value為從查 詢出來映射生成的Java對象。 sqlSession執(zhí)行insert、update、delete等操作commit提交后會清空緩存區(qū)域。一級緩存測試:
// 一級緩存默認(rèn)開啟,二級緩存的開啟需要配置// 一級緩存的作用域:當(dāng)前session@Testpublic void test1() {StuInfoMapper stuMapper = sqlSession.getMapper(StuInfoMapper.class);StuInfo stu = stuMapper.getStuInfoById(1);System.out.println(stu);// 這里是讀取的緩存里面的stuStuInfo stu1 = stuMapper.getStuInfoById(1);System.out.println(stu1);}只查詢一次
臟讀問題
簡單的說:基于mybatis中的緩存機(jī)制,查詢的結(jié)果是緩存中的結(jié)果,數(shù)據(jù)未得到即時(shí)更新。
// 緩存帶來的臟讀問題// 這里不開啟二級緩存@Testpublic void test2() {// 第一個(gè)sessionSqlSession sqlSession1 = sqlSessionFactory.openSession();StuInfoMapper stuInfoMapper1 = sqlSession1.getMapper(StuInfoMapper.class);StuInfo stu1 = stuInfoMapper1.getStuInfoById(1);System.out.println(stu1);// 第二個(gè)sessionSqlSession sqlSession2 = sqlSessionFactory.openSession();StuInfoMapper stuInfoMapper2 = sqlSession2.getMapper(StuInfoMapper.class);StuInfo stu2 = stuInfoMapper2.getStuInfoById(1);System.out.println(stu2);// 實(shí)現(xiàn)commit 修改操作 清空session1, 重新查詢stuInfoMapper1.updateStuInfoById(new StuInfo(1, "jack-->小李子",null, null, null));sqlSession1.commit();System.out.println("=============== after update... ================");stu1 = stuInfoMapper1.getStuInfoById(1);System.out.println("commit session1 重新查詢.. " + stu1);stu2 = stuInfoMapper2.getStuInfoById(1);System.out.println("一級緩存中的stu2, 臟讀... " + stu2);}3. 二級緩存,mapper 的namespace級別
啟用緩存
當(dāng)前mapper 啟用二級緩存
測試:
// 二級緩存在所有session之間共享。@Testpublic void test1() {// session1StuInfoMapper stuInfoMapper1 = sqlSession.getMapper(StuInfoMapper.class);StuInfo stu1 = stuInfoMapper1.getStuInfoById(1);// session1 關(guān)閉, 緩存到二級緩存中sqlSession.close();System.out.println(stu1);// 先讀二級緩存,不會查詢數(shù)據(jù)庫SqlSession sqlSession2 = sqlSessionFactory.openSession();StuInfoMapper stuInfoMapper2 = sqlSession2.getMapper(StuInfoMapper.class);StuInfo stu2 = stuInfoMapper2.getStuInfoById(1);System.out.println(stu2);}總結(jié)
以上是生活随笔為你收集整理的mybatis一级,二级缓存。缓存带来的脏读问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机H5模板样式
- 下一篇: mysql no listenter_为