日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅谈Mybatis的一级缓存和二级缓存

發布時間:2024/4/15 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈Mybatis的一级缓存和二级缓存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

MyBatis的緩存機制

緩存的引入

當我們大量執行重復的查詢SQL語句的時候,會頻繁的和數據庫進行通信,會增加查詢時間等影響用戶體驗的問題,可以通過緩存,以降低網絡流量,使網站加載速度更快.

MyBatis的一級緩存

默認情況下,MyBatis只啟用了本地的會話緩存,它僅僅對一個會話中的數據進行緩存。這也就是大家常說的MyBatis一級緩存,一級緩存的作用域是SqlSession。

第1種情況:同個session進行兩次相同查詢

代碼驗證

//測試一級緩存@Testpublic void testCache() throws IOException {//加載配置文件InputStream rs = Resources.getResourceAsStream("MyBatisConfig.xml");//獲取工廠建造類SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//獲取工廠對象SqlSessionFactory build = sqlSessionFactoryBuilder.build(rs);//獲取SqlSession對象SqlSession sqlSession = build.openSession(true);//得到代理的對象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//根據名字查詢Student stu1 = mapper.findStudentByName("小花花");Student stu2 = mapper.findStudentByName("小花花");/*這里相等,說明默認開啟一級緩存,就是在同一個sqlSession域中有效,只要查詢相同的語句,就是從一級緩存中獲取*/System.out.println("兩次查詢結果的學生對象是否是同一個:"+(stu1==stu2));//關閉會話sqlSession.close();rs.close();}

執行結果


由上面的執行結果得知
MyBatis是默認開啟一級緩存的,作用域是同一個SqlSession,在同一個sqlSession中查詢相同的sql語句,第一次查詢后會將結果對象存放在一級緩存中,在后面查詢相同的sql語句的時候會在一級緩存中去獲取,不用在與數據庫進行通信,大大降低了查詢速度.

第2種情況:同個session進行兩次不同的查詢。

** 代碼演示**

//測試一級緩存@Testpublic void testCache() throws IOException {//加載配置文件InputStream rs = Resources.getResourceAsStream("MyBatisConfig.xml");//獲取工廠建造類SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//獲取工廠對象SqlSessionFactory build = sqlSessionFactoryBuilder.build(rs);//獲取SqlSession對象SqlSession sqlSession = build.openSession(true);//得到代理的對象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//根據名字查詢Student stu1 = mapper.findStudentByName("小花花");Student stu2 = mapper.findStudentByName("小付");System.out.println("兩次查詢結果的學生對象是否是同一個:"+(stu1==stu2));//關閉會話sqlSession.close();rs.close();}

控制臺輸出

第3種情況:不同session,進行相同查詢。

** 代碼演示**

//測試一級緩存@Testpublic void testCache() throws IOException {//加載配置文件InputStream rs = Resources.getResourceAsStream("MyBatisConfig.xml");//獲取工廠建造類SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//獲取工廠對象SqlSessionFactory build = sqlSessionFactoryBuilder.build(rs);//獲取SqlSession對象SqlSession sqlSession = build.openSession(true);StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//獲取SqlSession2對象SqlSession sqlSession2 = build.openSession(true);StudentMapper mapper2 = sqlSession2.getMapper(StudentMapper.class);//根據名字查詢Student stu1 = mapper.findStudentByName("小花花");Student stu2 = mapper2.findStudentByName("小花花");System.out.println("兩次查詢結果的學生對象是否是同一個:"+(stu1==stu2));//關閉會話sqlSession.close();rs.close();}

控制臺輸出

第4種情況:同個session,查詢之后更新數據,再次查詢相同的語句。

代碼演示

//測試一級緩存@Testpublic void testCache() throws IOException {//加載配置文件InputStream rs = Resources.getResourceAsStream("MyBatisConfig.xml");//獲取工廠建造類SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//獲取工廠對象SqlSessionFactory build = sqlSessionFactoryBuilder.build(rs);//獲取SqlSession對象SqlSession sqlSession = build.openSession(true);//得到代理的對象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//根據名字查詢Student stu1 = mapper.findStudentByName("小花花");//修改數據stu1.setAge(18);//執行更新語句mapper.updateStudent(stu1);//再次查詢Student stu2 = mapper.findStudentByName("小花花");System.out.println("兩次查詢結果的學生對象是否是同一個:"+(stu1==stu2));//關閉會話sqlSession.close();rs.close();}

控制臺輸出

一級緩存結論

MyBatis一級緩存的運行過程是這樣的:執行SQL語句的過程中,首次執行它時從數據庫獲取的所有數據會被存儲在一段高速緩存中,今后執行這條語句時就會從高速緩存中讀取結果,而不是再次查詢數據庫。MyBatis提供了默認下基于Java HashMap的緩存實現。

重點是要明白:MyBatis執行SQL語句之后,這條語句的執行結果被緩存,以后再執行這條語句的時候,會直接從緩存中拿結果,而不是再次執行SQL。但是一旦執行新增或更新或刪除操作,緩存就會被清除。下面將分情況來驗證一下。

很明顯,以上各種情況驗證了一級緩存的概念,在同個SqlSession中,查詢語句相同的sql會被緩存,但是一旦執行新增或更新或刪除操作,緩存就會被清除。

MyBatis的二級緩存(全局緩存)

引入

MyBatis 一級緩存最大的共享范圍就是一個SqlSession內部,那么如果多個 SqlSession 需要共享緩存,則需要開啟二級緩存.

當二級緩存開啟后,同一個命名空間(namespace) 所有的操作語句,都影響著一個共同的 cache,也就是二級緩存被多個 SqlSession 共享,是一個全局的變量。當開啟緩存后,數據的查詢執行的流程就是 二級緩存 -> 一級緩存 -> 數據庫。

二級緩存開啟條件
二級緩存默認是不開啟的,需要手動開啟二級緩存,實現二級緩存的時候,MyBatis要求返回的**POJO必須是可序列化的**。開啟二級緩存的條件也是比較簡單.

在MyBatis核心配置文件中配置開啟二級緩存

<!-- 通知 MyBatis 框架開啟二級緩存 --> <settings><setting name="cacheEnabled" value="true"/> </settings>

在mapper配置文件中開啟當前命名空間的查詢結果存放在二級緩存中

<!-- 表示DEPT表查詢結果保存到二級緩存(共享緩存)cache 標簽有多個屬性,一起來看一些這些屬性分別代表什么意義eviction: 緩存回收策略,有這幾種回收策略LRU - 最近最少回收,移除最長時間不被使用的對象FIFO - 先進先出,按照緩存進入的順序來移除它們SOFT - 軟引用,移除基于垃圾回收器狀態和軟引用規則的對象WEAK - 弱引用,更積極的移除基于垃圾收集器和弱引用規則的對象默認是 LRU 最近最少回收策略flushinterval 緩存刷新間隔,緩存多長時間刷新一次,默認不清空,設置一個毫秒值readOnly: 是否只讀;true 只讀,MyBatis 認為所有從緩存中獲取數據的操作都是只讀操作,不會修改數據。MyBatis 為了加快獲取數據,直接就會將數據在緩存中的引用交給用戶。不安全,速度快。讀寫(默認):MyBatis 覺得數據可能會被修改size : 緩存存放多少個元素type: 指定自定義緩存的全類名(實現Cache 接口即可)blocking: 若緩存中找不到對應的key,是否會一直blocking,直到有對應的數據進入緩存。我這里就使用默認的,不去設置參數--><cacheeviction="FIFO"flushInterval="60000"size="512"readOnly="true"/>

實體類對象要Serializable序列化

@Data //這個注解是lombok包下的,可以自動幫我們添加getset方法等 public class Student implements Serializable {private Integer sid;private String name;private Integer age; }

代碼驗證

//測試一級緩存@Testpublic void testCache() throws IOException {//加載配置文件InputStream rs = Resources.getResourceAsStream("MyBatisConfig.xml");//獲取工廠建造類SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//獲取工廠對象SqlSessionFactory build = sqlSessionFactoryBuilder.build(rs);//獲取SqlSession對象SqlSession sqlSession = build.openSession(true);StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//根據名字查詢Student stu1 = mapper.findStudentByName("小花花");System.out.println("第一次查出的對象"+stu1);//關閉會話后,會將一級緩存的數據保存在二級緩存中sqlSession.close();//獲取SqlSession2對象SqlSession sqlSession2 = build.openSession(true);StudentMapper mapper2 = sqlSession2.getMapper(StudentMapper.class);//新的會話查詢就會從二級緩存中獲取數據Student stu2 = mapper2.findStudentByName("小花花");System.out.println("第二次查出的對象"+stu1);System.out.println("兩次查詢結果的學生對象是否是同一個:"+(stu1==stu2));//關閉會話sqlSession2.close();rs.close();}

控制臺輸出

圖解查詢語句執行流程

總結

以上是生活随笔為你收集整理的浅谈Mybatis的一级缓存和二级缓存的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。