Mybatis執(zhí)行流程、緩存原理及相關(guān)面試題匯總
一、Mybatis執(zhí)行流程
具體分析Mybatis是如何操作數(shù)據(jù)庫的!
1、定義我們的核心配置文件的路徑,這個路徑是從target/classes下開始找的!
String config = "mybatis-config.xml" ;
2、讀取這個config表示的文件
InputStream inputStream= Resources.getResourceAsStream(config);
3、創(chuàng)建SqlSessionFactoryBuilder對象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
4、創(chuàng)建SqlSessionFactory對象
SqlSessionFactory sessionFactory = builder.build(inputStream);
5、獲取SqlSession對象,從SqlSessionFactory中獲取
SqlSession sqlSession = sessionFactory.openSession();
6、【重點(diǎn)】執(zhí)行我們的執(zhí)行的的sql語句標(biāo)識。sql文件中的namespace + sql標(biāo)簽的Id值
String sqlId = "com.sqx.dao.UserMapper.getUserById";
7、執(zhí)行sql語句,通過sqlId找到語句,并執(zhí)行!
List<Object> objects = sqlSession.selectList(sqlId);
8、關(guān)閉SqlSession
sqlSession.close();
總結(jié)
Myabtis啟動的時候會加載mybatis-config.xml這個核心配置文件,得到要操作的數(shù)據(jù)庫以及我們Mapper文件的的信息,然后將其以數(shù)據(jù)流的形式保存起來傳給SqlSessionFactoryBuilder,創(chuàng)造出對應(yīng)該數(shù)據(jù)庫的SqlSessionFactory工廠,工廠生產(chǎn)SqlSession,這個SqlSession中包含了對該庫的增刪改查方法,我們需要通過namespace + sqlId
來確定我們執(zhí)行的是哪個sql,這一步操作可以通過SqlSeesion.getMapper()拿到接口,通過調(diào)用接口的方法(方法綁定了我們的sql,包含namespace + sqlId
),執(zhí)行對應(yīng)的SQL語句!
二、Mybatis緩存
Mybatis緩存無論是一級緩存還是二級緩存都是本地緩存,都會占用JVM的內(nèi)存,一旦Java停止緩存失效!
1、一級緩存
概述
- 一級緩存保存在我們的SqlSession當(dāng)中
- 只要是同一個SqlSesisson(與數(shù)據(jù)庫建立的會話)就會使用同一個緩存
- 一級緩存是我們Mybatis默認(rèn)開啟的!
如下是對一級緩存進(jìn)行測試:
查看我們的測試結(jié)果
采用不同的SqlSession測試數(shù)據(jù),進(jìn)行如下修改!
我們再次查看測試結(jié)果
得出結(jié)論我們的一級緩存只是在同一個SqlSession當(dāng)中有效!
2、二級緩存
概述
二級緩存又稱"全局緩存",是基于namespace級別的緩存,一個namespace對應(yīng)一個二級緩存!
工作機(jī)制:
- 一個會話查詢一條數(shù)據(jù),這個數(shù)據(jù)會被放在一級緩存當(dāng)中
- 當(dāng)我們會話關(guān)閉的時候,會把這個數(shù)據(jù)從1級緩存遷入二級緩存當(dāng)中,新的會話就可以在二級緩存當(dāng)中找到這個數(shù)據(jù)!
- 不同的會話查詢不同的namespace的時候,會將不同namespace中的數(shù)據(jù)緩存到自己對應(yīng)的緩存(map)中!
使用步驟 :
只需在需要使用緩存的namespace 中加入< cache/>
即可
<!--在當(dāng)前Mapper.xml中使用二級緩存,并配置相關(guān)參數(shù)--> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> eviction :緩存的回收策略 LRU(最長時間未使用)、LFU(訪問次數(shù)最少)、FIFO(默認(rèn))、SOFT(軟引用)、WEAK(弱引用) flushInterval : 緩存刷新間隔 緩存多久清空一次,默認(rèn)是不會清空的,設(shè)置一個毫秒值 readOnly :是否只讀 size :緩存存放多少元素
我們還可以通過配置實(shí)現(xiàn)自定義緩存
<!-- 開啟mybatis的二級緩存,其本質(zhì)還是我們mybatis幫我們實(shí)現(xiàn)了自身提供的緩存接口Cache, 也就是cache標(biāo)簽的type屬性默認(rèn)指定了緩存策略 --> <cache type=""/> <!--本質(zhì)上就是這種寫法,我們可通該修改type來選擇自定緩存策略--> <cache type="rg.apache.ibatis.cache.impl.PerpetualCache"/>
3、緩存原理
如圖所示
緩存執(zhí)行流程
- 當(dāng)我們的sql執(zhí)行的時候,先去二級緩存namespace中查看是否存在緩存,
- 然后如果二級緩存不存在,查看當(dāng)前sqlSession中一級緩存中是否存在,
- 最后一、二級緩存中都不存在的話那么就去數(shù)據(jù)庫查詢,
- 接著會將查詢出來的結(jié)果保存在我們的一級緩存當(dāng)中,
- 當(dāng)前會話(SqlSession)結(jié)束,就會將一級緩存中的數(shù)據(jù),同步到我們的二級緩存
三、相關(guān)面試題
1、為什么說 Mybatis 是半自動ORM映射工具?它與全自動的區(qū)別在哪里?
什么是ORM
ORM(Object Relational Mapping),對象關(guān)系映射,是一種為了解決關(guān)系型數(shù)據(jù)庫數(shù)據(jù)與簡單 Java 對象(POJO)建里映射關(guān)系的技術(shù)。
為什么說 Mybatis 是半自動ORM映射工具?它與全自動的區(qū)別在哪里?
- 首先,像 Hibernate、JPA 這種屬于全自動 ORM 映射工具,使用 Hibernate 查詢關(guān)聯(lián)對象或者關(guān)聯(lián)集合對象時,可以根據(jù)對象關(guān)系模型直接獲取,所以它是全自動的。
- 而 Mybatis 在查詢關(guān)聯(lián)對象或關(guān)聯(lián)集合對象時,需要手動編寫 sql 來完成,所以,稱之為半自動 ORM 映射工具。
- 換句話來解釋就是說 MyBatis 是 半自動 ORM 最主要的一個原因是,它需要在 XML 或者注解里通過手動或插件生成 SQL,才能完成 SQL 執(zhí)行結(jié)果與對象映射綁定。
2、簡述一下Mybatis的執(zhí)行流程吧 ?
- MyBatis 是以一個 SqlSessionFactory 實(shí)例為核心,SqlSessionFactory 的實(shí)例可以通過 SqlSessionFactoryBuilder 獲得。
- SqlSessionFactoryBuilder 可以從 XML 配置文件或一個預(yù)先配置的 Configuration 實(shí)例來構(gòu)建出 SqlSessionFactory 實(shí)例。
- SqlSessionFactory 實(shí)例工廠可以生產(chǎn) SqlSession ,它里面提供了在數(shù)據(jù)庫執(zhí)行 SQL 命令所需的所有方法。
3、說一下Mybatis的優(yōu)缺點(diǎn) ?
優(yōu)點(diǎn)
- 基于SQL語句編寫、相當(dāng)靈活,SQL寫在XML文件當(dāng)中,解除了sql與程序代碼的耦合,便于統(tǒng)一管理
- 消除了JDBC的冗余代碼、能夠與Spring很好的集成
缺點(diǎn)
- SQL語句的編寫工作量大,尤其是字段多,關(guān)聯(lián)表多的情況下,對開發(fā)人員的SQL語句功底有一定的要求
- SQL語句依賴數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫移植性差,不能隨意更換數(shù)據(jù)庫
4、#{} 和 ${} 的區(qū)別是什么 ?
- #{} 是占位符,預(yù)編譯處理,${}是拼接符,字符串替換,沒有預(yù)編譯處理
- mybatis在處理#{}的時候,#{} 傳入的參數(shù)是字符串,會將SQL中的#{} 替換為?調(diào)用PreparedStatement的Set方法賦值
- myabtsi在處理的 時 候 , 就 是 原 值 傳 入 , 就 是 把 {}的時候,就是原值傳入,就是把的時候,就是原值傳入,就是把{}替換為傳來的值
- #{}通過編譯預(yù)處理可以有效地防止SQL注入問題,提高系統(tǒng)的安全性,${}則不能防止SQL注入
5、Mybatis的動態(tài)SQL有什么作用?執(zhí)行原理是什么?有哪些常用標(biāo)簽?
- mybatis動態(tài)sql可以在xml映射文件內(nèi),以標(biāo)簽的形式編寫動態(tài)sql
- 執(zhí)行原理:根據(jù)參數(shù)表達(dá)式的值完成邏輯判斷,并且動態(tài)拼接sql
- mybatis提供9種動態(tài)sql的標(biāo)簽:trim、where、set、foreach、if、choose、when、otherwise、bind
總結(jié)
到此這篇關(guān)于Mybatis執(zhí)行流程、緩存原理及相關(guān)面試題的文章就介紹到這了,更多相關(guān)Mybatis執(zhí)行流程、緩存及面試題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java編程實(shí)現(xiàn)數(shù)組轉(zhuǎn)成list及l(fā)ist轉(zhuǎn)數(shù)組的方法
這篇文章主要介紹了Java編程實(shí)現(xiàn)數(shù)組轉(zhuǎn)成list及l(fā)ist轉(zhuǎn)數(shù)組的方法,結(jié)合實(shí)例形式較為詳細(xì)的總結(jié)分析了java實(shí)現(xiàn)數(shù)組與list之間相互轉(zhuǎn)換的操作技巧,需要的朋友可以參考下2017-09-09JAVA中String類與StringBuffer類的區(qū)別
這篇文章主要為大家詳細(xì)介紹了JAVA中String類與StringBuffer類的區(qū)別,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12使用idea遠(yuǎn)程調(diào)試jar包的配置過程
這篇文章主要介紹了使用idea遠(yuǎn)程調(diào)試jar包的配置過程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09使用Feign調(diào)用注解組件(實(shí)現(xiàn)字段賦值功能)
這篇文章主要介紹了使用Feign調(diào)用注解組件(實(shí)現(xiàn)字段賦值功能),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03使用Jacoco獲取 Java 程序的代碼執(zhí)行覆蓋率的步驟詳解
這篇文章主要介紹了使用Jacoco獲取 Java 程序的代碼執(zhí)行覆蓋率的步驟詳解,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-03-03