框架2 MyBatis

參考:
MyBatis結(jié)構(gòu)和組件 http://www.reibang.com/p/75a6a2297c69
MyBatis運(yùn)行流程炉峰、緩存和插件 http://www.reibang.com/p/4fe280c44294
MyBatis緩存
http://www.reibang.com/p/7a98dda8cd75
http://www.reibang.com/p/8801d1aa20a0
MyBatis常見面試題 https://blog.csdn.net/a745233700/article/details/80977133

一.MyBatis概述

1.MyBatis
  • 支持普通SQL查詢蔓搞、存儲(chǔ)過程和高級(jí)映射的持久層框架
  • 消除了幾乎所有的JDBC代碼和參數(shù)的手工設(shè)置以及對(duì)結(jié)果集的封裝
  • MyBatis可使用XML或注解進(jìn)行配置张足,將接口和Java的POJO映射成數(shù)據(jù)庫(kù)記錄
  • 專注于Sql本身,適用于對(duì)性能要求很高或需求變化較多的項(xiàng)目
2.MyBatis特點(diǎn)
  • 優(yōu)點(diǎn)
    1)簡(jiǎn)單易學(xué)吃媒。MyBatis本身小而簡(jiǎn)單
    2)靈活涂籽。MyBatis允許自由編寫Sql語(yǔ)句
    3)Sql和程序代碼解耦,且提供xml標(biāo)簽支持編寫動(dòng)態(tài)sql
    4)提供映射標(biāo)簽毅否,支持對(duì)象與數(shù)據(jù)庫(kù)的ORM字段關(guān)系映射
    5)與JDBC相比亚铁,減少了50%以上的代碼量
  • 缺點(diǎn)
    1)自由編寫Sql語(yǔ)句意味較大的工作量
    2)Sql語(yǔ)句依賴于數(shù)據(jù)庫(kù),導(dǎo)致數(shù)據(jù)庫(kù)無法隨意更換搀突,移植性差

二.MyBatis原理

1.MyBatis功能結(jié)構(gòu)
  • API接口層
    開發(fā)人員通過接口API操縱數(shù)據(jù)庫(kù)刀闷,接口層接收請(qǐng)求后會(huì)調(diào)用數(shù)據(jù)處理層完成具體的數(shù)據(jù)處理
  • 數(shù)據(jù)處理層
    根據(jù)API接口層調(diào)用的請(qǐng)求完成一次數(shù)據(jù)庫(kù)操作熊泵,負(fù)責(zé)具體的Sql查找、Sql解析和執(zhí)行結(jié)果映射處理等
  • 基礎(chǔ)支撐層
    實(shí)現(xiàn)連接管理甸昏、事務(wù)管理和執(zhí)行結(jié)果映射處理等基礎(chǔ)功能顽分,為數(shù)據(jù)處理層提供基礎(chǔ)支持
MyBatis功能結(jié)構(gòu)
2.MyBatis運(yùn)行流程
  • 加載配置
    從配置文件或注解獲取配置信息并加載成MappedStatement對(duì)象,此對(duì)象=傳入?yún)?shù)的映射配置+要執(zhí)行的Sql語(yǔ)句+結(jié)果的映射配置
  • Sql解析
    API接口層接收調(diào)用請(qǐng)求時(shí)施蜜,根據(jù)傳入的Sql的Id找到對(duì)應(yīng)的MappedStatement卒蘸,再根據(jù)傳入的參數(shù)對(duì)象解析MappedStatement獲得最終要執(zhí)行的Sql語(yǔ)句和參數(shù)
  • Sql執(zhí)行
    獲取數(shù)據(jù)庫(kù)連接翻默,執(zhí)行Sql解析獲得的Sql語(yǔ)句和參數(shù)缸沃,并返回結(jié)果
  • 結(jié)果映射
    將數(shù)據(jù)庫(kù)返回結(jié)果按映射配置轉(zhuǎn)換成需要的數(shù)據(jù)類型并返回
MyBatis運(yùn)行流程
3.MyBatis主要構(gòu)件
  • SqlSession
    MyBatis主要頂層API,負(fù)責(zé)和數(shù)據(jù)庫(kù)交互的會(huì)話修械,完成增刪查改操作
  • Executor
    MyBatis執(zhí)行器趾牧,是MyBatis調(diào)度和核心,負(fù)責(zé)Sql語(yǔ)句生成和查詢緩存的維護(hù)
  • StatementHandler
    封裝了JDBC Statement肯污,負(fù)責(zé)JDBC中對(duì)Statement的操作翘单,如設(shè)置參數(shù)、將Statement結(jié)果集轉(zhuǎn)換為L(zhǎng)ist集合
  • ParameterHandler
    將用戶傳遞的參數(shù)轉(zhuǎn)換為JDBC Statement所需的參數(shù)
  • ResultSetHandler
    將JDBC返回的ResultSet結(jié)果集轉(zhuǎn)換為L(zhǎng)ist集合
  • TypeHandler
    負(fù)責(zé)Java數(shù)據(jù)類型和JDBC數(shù)據(jù)類型間的映射和轉(zhuǎn)換
  • MappedStatement
    維護(hù)<select/update/delete/insert>節(jié)點(diǎn)的封裝
  • SqlSource
    根據(jù)用戶傳遞的parameterObject蹦渣,動(dòng)態(tài)生成Sql語(yǔ)句哄芜,將信息封裝到BoundSql對(duì)象并返回
  • BoundSql
    表示動(dòng)態(tài)生成的Sql語(yǔ)句及相應(yīng)的參數(shù)信息
  • Configuration
    維持MyBatis所有的配置信息
MyBatis主要組件及其相互關(guān)系

三.MyBatis緩存

1.緩存總覽
MyBatis流程圖
  • 緩存在流程的Executor使用,Executor執(zhí)行查詢時(shí)先判斷緩存柬唯,若緩存命中认臊,直接返回緩存中的結(jié)果,否則繼續(xù)之后的步驟查詢數(shù)據(jù)庫(kù)
  • MyBatis使用底層為HashMap的Cache對(duì)象锄奢,通過各種裝飾類對(duì)其層層裝飾失晴,以實(shí)現(xiàn)各種功能和隔離不同功能邏輯
  • MyBatis緩存分為一級(jí)緩存二級(jí)緩存,默認(rèn)開啟一級(jí)緩存
  • 數(shù)據(jù)查詢優(yōu)先級(jí):二級(jí)緩存---一級(jí)緩存---數(shù)據(jù)庫(kù)
2.一級(jí)緩存
  • 緩存默認(rèn)Session級(jí)別(可設(shè)為Statement)拘央,同一會(huì)話的重復(fù)Sql語(yǔ)句可使用緩存
  • 不同Session間緩存相互獨(dú)立师坎,分布式查詢可能讀到臟數(shù)據(jù)
  • Executor收到Sql語(yǔ)句后飒泻,先查詢自己的localCache(HashMap)渴频,緩存命中則直接返回結(jié)果珊搀,緩存命中失敗則繼續(xù)查詢數(shù)據(jù)庫(kù)后將結(jié)果寫入localCache
3.二級(jí)緩存
  • 解決跨SqlSession的緩存問題,MyBatis提供二級(jí)緩存功能
  • 二級(jí)緩存使用CachingExecutor包裝Executor袱箱,CachingExecutor負(fù)責(zé)與全局二級(jí)緩存交互
二級(jí)緩存流程圖
  • CachingExecutor優(yōu)先查詢二級(jí)緩存,如沒有匹配則委托給它包裝的Executor匹配的一級(jí)緩存
Executor
  • 二級(jí)緩存全局有效义矛,劃分到mapper級(jí)別(namespace定義)发笔,而非整個(gè)application使用同一緩存
  • 由于不同namespace的二級(jí)緩存相互獨(dú)立,多表查詢時(shí)容易出現(xiàn)臟數(shù)據(jù)凉翻。如果將多個(gè)表的操作放在相同namespace會(huì)導(dǎo)致緩存顆粒度過大了讨,頻繁刷新緩存
  • MyBatis Cache是基于本地的,分布式環(huán)境下必然會(huì)讀取臟數(shù)據(jù),用戶自定義實(shí)現(xiàn)MyBatis的Cache接口開發(fā)成本較高前计,直接使用Redis/Memcached等分布式緩存成本更低胞谭,安全性更高

四.MyBatis插件

1.插件概述
  • MyBatis插件又稱攔截器,采用責(zé)任鏈模式男杈,通過動(dòng)態(tài)代理組織多個(gè)插件(攔截器)丈屹,改變MyBatis默認(rèn)行為(如Sql重寫)
  • 插件通過動(dòng)態(tài)代理方式在已映射語(yǔ)句執(zhí)行過程中的某一點(diǎn)進(jìn)行攔截調(diào)用
  • MyBatis插件需要實(shí)現(xiàn)Interceptor接口,該接口主要方法有
    1)setProperties:配置MyBatis插件的自定義屬性
    2)plugin:插件用來封裝目標(biāo)對(duì)象的方法伶棒,通過該方法可返回目標(biāo)對(duì)象本身或一個(gè)它的代理
    3)interceptor:攔截時(shí)執(zhí)行的方法
    4)plugin接口

五.MyBatis與其他框架

1.MyBatis與iBatis
  • iBatis是Apache的一個(gè)開源項(xiàng)目旺垒,該項(xiàng)目在2010年從Apache Software Foundation遷移到Google Code,并改名MyBatis
  • MyBatis是IBatis的升級(jí)版肤无,MyBatis在以下方面改善了IBatis功能
    1)MyBatis實(shí)現(xiàn)接口綁定先蒋,使用更方便
    2)MyBatis改進(jìn)了對(duì)象關(guān)系映射(association和collection)
    3)MyBatis在動(dòng)態(tài)Sql語(yǔ)句中采用OGNL表達(dá)式取代節(jié)點(diǎn)配置
2.MyBatis與Hibernate
  • MyBatis
    1)Mybatis真正實(shí)現(xiàn)了Java代碼和Sql分離
    2)Mybatis自行編寫sql,靈活度高宛渐,便于Sql優(yōu)化
  • Hibernate
    1)Hibernate數(shù)據(jù)庫(kù)無關(guān)性好竞漾,適用于需求固定的定制化軟件,但學(xué)習(xí)成本高
    2)Hibernate大大降低了對(duì)象和數(shù)據(jù)庫(kù)的耦合度皇忿,其數(shù)據(jù)移植性遠(yuǎn)大于MyBatis
    3)Hibernate在多表關(guān)聯(lián)查詢時(shí)表現(xiàn)較差
    4)Hibernate效率較低畴蹭,Sql自動(dòng)生成,不便于人工優(yōu)化鳍烁,調(diào)優(yōu)需要相當(dāng)經(jīng)驗(yàn)積累
  • 場(chǎng)景選擇
    1)數(shù)據(jù)量大(超過千萬級(jí)別的表/單次業(yè)務(wù)大批量數(shù)據(jù)(百萬條)提交或讀取)適用MyBatis
    2)表關(guān)聯(lián)度(主要業(yè)務(wù)表的關(guān)聯(lián)表>20)復(fù)雜適用MyBatis

六.常見面試題

1.SqlSession創(chuàng)建過程和相關(guān)對(duì)象生命周期叨襟?
  • SqlSessionFactoryBuilder---SqlSessionFactory---SqlSession---SqlMapper
  • SqlSessionFactoryBuilder在構(gòu)建SqlSessionFactory后即可銷毀
  • SqlSessionFactory存在于整個(gè)MyBatis應(yīng)用中,類似數(shù)據(jù)庫(kù)連接池幔荒,不斷創(chuàng)建SqlSession
  • SqlSession類似于數(shù)據(jù)庫(kù)連接糊闽,在完成一次業(yè)務(wù)請(qǐng)求后回收
  • SqlMapperSqlSession創(chuàng)建,生命周期SqlMapper<=SqlSession
2.#{}和${}的區(qū)別爹梁?
  • 前者’#{}‘是預(yù)編譯處理右犹,MyBatis預(yù)編譯時(shí)會(huì)將#{}替換為?號(hào),調(diào)用PreparedStatement的set方法賦值
  • 后者是xml文件的字符串替換姚垃,MyBatis會(huì)把${}替換成變量的值
  • 使用#{}可防止Sql注入念链,提高安全性
3.實(shí)體類的屬性名和表中字段名不一樣該如何映射?
  • 在Sql語(yǔ)句中定義與實(shí)體類屬性名一樣的別名
  • 通過<resultMap>映射字段名和實(shí)體類屬性名
    <select id="getOrder" parameterType="int" resultMap="orderresultmap">
        select * from orders where order_id=#{id}
    </select>
 
   <resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
        <!–用id屬性來映射主鍵字段–>
        <id property=”id” column=”order_id”>
 
        <!–用result屬性來映射非主鍵字段积糯,property為實(shí)體類屬性名掂墓,column為數(shù)據(jù)表中的屬性–>
        <result property = “orderno” column =”order_no”/>
        <result property=”price” column=”order_price” />
    </reslutMap>
4.每個(gè)xml映射文件都有一個(gè)Dao接口與之對(duì)應(yīng),Dao接口的工作原理是什么看成?Dao接口里的方法在參數(shù)不同時(shí)是否可以重載君编?
  • Dao接口即Mapper接口:映射的xml文件的namespace接口的全限定名;映射文件中MappedStatement的id接口的方法名川慌;接口方法的參數(shù)就是傳遞給sql的參數(shù)
  • 調(diào)用接口方法時(shí)吃嘿,通過接口全限定名+方法名定位唯一的MappedStatement
  • 由于僅使用接口全限定名和方法名定位MappedStatement祠乃,故不同參數(shù)的接口方法不能重載
  • 此外,不同的xml配置文件兑燥,如果設(shè)置不同的namespace亮瓷,則id可重復(fù),否則不可重復(fù)
5.MyBatis是如何進(jìn)行分頁(yè)的贪嫂?分頁(yè)插件的原理是什么寺庄?
  • MyBatis使用RowBounds對(duì)象針對(duì)ResultSet結(jié)果集執(zhí)行內(nèi)存分頁(yè),也可以在Sql內(nèi)直接書寫帶有物理分頁(yè)的參數(shù)實(shí)現(xiàn)物理分頁(yè)
  • 分頁(yè)插件實(shí)現(xiàn)MyBatis提供的插件接口力崇,在插件的攔截方法里攔截并重寫待執(zhí)行的sql
6.MyBatis動(dòng)態(tài)Sql是做什么的斗塘?其執(zhí)行原理是什么?
  • MyBatis允許在xml映射文件中以標(biāo)簽形式編寫動(dòng)態(tài)Sql亮靴,完成邏輯判斷和動(dòng)態(tài)拼接Sql的功能
  • MyBatis提供 trim | where | set | foreach | if | choose | when | otherwise | bid 9種動(dòng)態(tài)sql標(biāo)簽
  • 執(zhí)行原理為
    1)使用OGNL從sql參數(shù)對(duì)象中計(jì)算表達(dá)式的值
    2)根據(jù)表達(dá)式值動(dòng)態(tài)拼接Sql
7.MyBatis是否支持延遲加載馍盟?其實(shí)現(xiàn)原理是什么?
  • 延遲加載又稱懶加載茧吊,用于處理N+1性能問題
  • N+1問題指映射集合(resultMap)級(jí)聯(lián)時(shí)贞岭,我們需要的數(shù)據(jù)少于數(shù)據(jù)庫(kù)查出的數(shù)據(jù),浪費(fèi)性能且加重?cái)?shù)據(jù)庫(kù)負(fù)擔(dān)
  • MyBatis僅支持association關(guān)聯(lián)對(duì)象(1對(duì)1)和collection關(guān)聯(lián)集合(1對(duì)多)的延遲加載搓侄,配置文件中參數(shù)LazyLoadingEnabled=true|false設(shè)置是否開啟延遲加載
  • MyBatis通過動(dòng)態(tài)代理實(shí)現(xiàn)延遲加載
    參考:https://my.oschina.net/wenjinglian/blog/1857581?from=singlemessage
8.使用MyBatis的mapper接口調(diào)用時(shí)有哪些要求瞄桨?
  • Mapper接口方法名和mapper.xml定義的sql的id相同
  • Mapper接口方法的輸入?yún)?shù)類型和mapper.xml定義的sql的parameterType類型相同
  • Mapper接口方法的輸出參數(shù)類型和mapper.xml定義的sql的resultType類型相同
  • Mapper.xml的namespace即是mapper接口的類路徑
9.mapper有哪幾種編寫方式?
  • 接口實(shí)現(xiàn)類繼承SqlSessionDaoSupport類
  • 使用org.mybatis.spring.mapper.MapperFactoryBean
  • 使用mapper掃描器
10.mapper如何傳遞多個(gè)參數(shù)讶踪?
  • xml使用#{0}接收dao層第一個(gè)參數(shù)芯侥,#{1}接收第二個(gè)參數(shù),以此類推
  • 使用@param注解
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乳讥,一起剝皮案震驚了整個(gè)濱河市柱查,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌云石,老刑警劉巖唉工,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異汹忠,居然都是意外死亡淋硝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門宽菜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奖地,“玉大人,你說我怎么就攤上這事赋焕。” “怎么了仰楚?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵隆判,是天一觀的道長(zhǎng)犬庇。 經(jīng)常有香客問我,道長(zhǎng)侨嘀,這世上最難降的妖魔是什么臭挽? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮咬腕,結(jié)果婚禮上欢峰,老公的妹妹穿的比我還像新娘。我一直安慰自己涨共,他們只是感情好纽帖,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著举反,像睡著了一般懊直。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上火鼻,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天室囊,我揣著相機(jī)與錄音,去河邊找鬼魁索。 笑死融撞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的粗蔚。 我是一名探鬼主播尝偎,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼支鸡!你這毒婦竟也來了冬念?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬榮一對(duì)情侶失蹤牧挣,失蹤者是張志新(化名)和其女友劉穎急前,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瀑构,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裆针,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寺晌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片世吨。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖呻征,靈堂內(nèi)的尸體忽然破棺而出耘婚,到底是詐尸還是另有隱情,我是刑警寧澤陆赋,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布嚷闭,位于F島的核電站赖临,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏兢榨。R本人自食惡果不足惜嗅榕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凌那。 院中可真熱鬧,春花似錦案怯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至局蚀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扶欣,已是汗流浹背千扶。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留髓绽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓顺呕,卻偏偏與公主長(zhǎng)得像括饶,于是被迫代替她去往敵國(guó)和親图焰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容