2021年MyBatis核心面試題

首先Mybatis是一個優(yōu)秀的持久層ORM框架咒程,它對jdbc的操作數據庫的過程進行封裝,使得開發(fā)者只需要關注SQL本身吁伺。不需要花費精力去處理一些重復和繁瑣的步驟涛酗。最后通過java對象和statement中的sql進行映射生成最終執(zhí)行的sql語句。最后由mysql框架執(zhí)行sql并將結果映射成java對象并返回沈跨。

ORM:對象關系映射衫冻,簡單點說就是將數據庫中的表和java中的對象建立映射關系,可以讓我們操作對象來間接的操作數據庫谒出。

半ORM:在查詢關聯(lián)對象或關聯(lián)集合對象時隅俘,需要手動編寫sql來完成邻奠。

MyBatis編程步驟

  • 創(chuàng)建SqlSessionFactory
  • 通過SqlSessionFactory創(chuàng)建SqlSession
  • 通過sqlsession執(zhí)行數據庫操作
  • 調用session.commit()提交事務
  • 調用session.close關閉會話

MyBatis的工作原理

  • 讀取MyBatis配置文件。(獲取MyBatis的運行環(huán)境等信息)
  • 加載映射文件为居。(SQL映射文件碌宴,其中配置了操作數據庫的SQL語句)
  • 構造會話工廠:通過MyBatis的環(huán)境等配置信息構建會話工廠SqlSessionFactory
  • 創(chuàng)建會話對象:有會話工廠創(chuàng)建SqlSession對象,該對象包括了執(zhí)行SQL語句的所有方法
  • Executor執(zhí)行器:根據SqlSession傳遞的參數動態(tài)的生成需要執(zhí)行的SQL語句蒙畴,同時負責查詢緩存的維護
  • Mappedstatement對象:用于存儲要映射的SQL語句的id贰镣、參數等信息
  • 輸入參數映射:參數類型可以為Map、List等集合類型也可以使用基本數據類型和POJO類型
  • 輸出結果映射:和輸入類似膳凝。

MyBatis的優(yōu)點

  • 基于SQL語句編程碑隆,相當靈活。SQL寫在XML中蹬音,解除sql與程序代碼的耦合上煤,便于統(tǒng)一管理。提供XML標簽,支持編寫動態(tài)SQL語句,并可重用
  • 消除了 JDBC 大量冗余的代碼狰域,不需要手動開關連接;
  • 很好的與各種數據庫兼容
  • 能夠與 Spring 很好的集成独泞;
  • 提供映射標簽,支持對象與數據庫的 ORM 字段關系映射苔埋;提供對象關系映射標簽懦砂,支持對象關系組件維護。

MyBatis框架的缺點

  • SQL 語句的編寫工作量較大组橄,尤其當字段多孕惜、關聯(lián)表多時,對開發(fā)人員編寫SQL 語句的功底有一定要求晨炕。
  • SQL 語句依賴于數據庫衫画,導致數據庫移植性差,不能隨意更換數據庫瓮栗。

MyBatis與Hibernate有哪些不同

  • MyBatis是一個半ORM框架削罩,需要自己編寫sql語句,靈活性高费奸,但是需要自定義多套sql映射文件弥激,工作量大
  • Hibernate數據庫無關性好,節(jié)省代碼愿阐,提高效率

#{}和${}的區(qū)別

  • #{}:是預編譯處理微服,會把sql中的#{}替換為?缨历,調用PreoaredStatement的set方法來賦值
  • {}:是字符串替換以蕴,用于標簽屬性值和sql內部糙麦,屬于靜態(tài)文本替換。把{}替換為變量的值丛肮。

使用#{}可以有效的防止SQL注入赡磅,提高系統(tǒng)的安全性 。

當實體類的屬性名和表中的字段名不一致如何處理

  • 通過在查詢的sql語句中定義字段名的別名宝与,讓字段名的別名和實體類的屬性名一致焚廊。

  • 通過<resultMap>類映射字段名和實體類屬性名的一一對應的關系

模糊查詢like怎么編寫

  • 在Java代碼中添加sql通配符
  • 在sql語句中拼接通配符(但是會引起sql注入問題)

通常一個Xml映射文件,都會寫一個Dao接口與之對應习劫。那么Dao接口的工作原理是什么咆瘟。

Dao接口就是Mapper接口。

  • 接口的全限定名就是映射文件的namespace的值
  • 接口的方法名就是映射文件中Mapper的Statement的id值
  • 接口方法內的參數就是傳遞給sql的參數

Mapper接口是沒有實現類的诽里,當調用接口方法的時候袒餐,接口的全限定名+方法名拼接字符串作為key值,可以唯一定位一個MapperStatement须肆。在MyBatis中匿乃,每一個<select>桩皿、<insert>豌汇、<update>、<delete>標簽都會被解析為一個MapperStatement對象

Dao接口的方法泄隔,參數不同時拒贱,方法能重載嗎

Mapper接口里的方法,是不能重載的佛嬉,因為使用全限定名+方法名的保存和尋找策略逻澳。所以不能重載。

Mapper接口的工作原理是JDK動態(tài)代理暖呕,MyBatis運行時會使用JDK動態(tài)代理為Mapper接口生成代理對象proxy斜做,代理對象會攔截接口方法,轉而執(zhí)行MapperStatement所代表的sql湾揽,然后將sql執(zhí)行結果返回瓤逼。

MyBatis是如何進行分頁的以及分頁插件的原理是什么

MyBatis使用RowBounds對象進行分頁,它是針對ResultSet結果集執(zhí)行的內存分頁库物,而非物理分頁霸旗。可以在sql內直接書寫帶有物理分頁的參數來完成物理的分頁功能戚揭,或者使用分頁插件來完成物理分頁

分頁插件的基本原理就是使用MyBatis提供的插件接口诱告,實現自定義插件,在插件的攔截方法內攔截待執(zhí)行的sql民晒,然后重寫sql精居,根據dialect锄禽,添加對應的物理分頁語句和物理分頁參數。

Mybati是如何將sql執(zhí)行機構封裝為對象并返回的箱蟆?有哪些映射形式

  • 使用<resultMap>標簽沟绪,逐一定義數據庫列名和對象屬性名之間的映射關系。
  • 使用sql列的別名功能空猜,將列別名書寫為對象屬性名

有了列名和屬性名的映射關系后绽慈,MyBatis通過反射創(chuàng)建對象,同時使用反射給對象的屬性逐一賦值并返回辈毯,那些找不到映射關系的屬性坝疼,是無法完成賦值的

如何進行批量插入

如何獲取自動生成的主鍵值

  • 使用JDBC內置方法
  • 插入后查詢獲取
  • 插入前查詢獲取主鍵

如何在mapper中傳遞多個參數

  • Dao層函數
  • 使用@param注解
  • 多個參數封裝成map

MyBatis動態(tài)sql

MyBatis動態(tài)sql可以在Xml映射文件內,以標簽的形式編寫動態(tài)sql谆沃,執(zhí)行原理是根據表達式的值完成邏輯判斷并動態(tài)拼接sql功能

MyBatis提供了九種sql標簽

  • trim
  • where
  • set
  • foreach
  • if
  • choose
  • when
  • otherwise
  • bind

XML文件標簽

  • select
  • insert
  • update
  • delete
  • resultMap
  • parameterMap
  • sql
  • include
  • selectKey

MyBatis的Xml映射文件中钝凶,不同的Xml文件id是否可以重復

如果配置了namespace那么id可以重復,要是沒有配置namespace唁影,id就不可以重復

MyBatis實現一對一有幾種方式

  • 聯(lián)合查詢

    • 幾個表聯(lián)合查詢耕陷,只查詢一次,通過配置collection節(jié)點
  • 嵌套查詢

    • 先查一個表据沈,再根據查出的id去另外一個表里查詢數據哟沫,也是通過配置collection,但是另外一個表的查詢通過select節(jié)點配置

MyBatis是否支持延遲加載锌介,以及如何實現

Mybatis僅支持association關聯(lián)對象和collection關聯(lián)集合對象的延遲加載嗜诀。可以通過配置lazyLoadingEnabled來進行配置孔祸。

原理

使用 CGLIB 創(chuàng)建目標對象的代理對象隆敢,當調用目標方法時,進入攔截器方法崔慧,比如調用 a.getB().getName()拂蝎,攔截器 invoke()方法發(fā)現 a.getB()是null 值,那么就會單獨發(fā)送事先保存好的查詢關聯(lián) B 對象的 sql惶室,把 B 查詢上來温自,然后調用 a.setB(b),于是 a 的對象 b 屬性就有值了拇涤,接著完成 a.getB().getName()方法的調用捣作。這就是延遲加載的基本原理。

MyBatis的緩存

  • 一級緩存: 基于 PerpetualCache 的 HashMap 本地緩存鹅士,其存儲作用域為Session券躁,當 Session flush 或 close 之后,該 Session 中的所有 Cache 就將清空,默認打開一級緩存也拜。
  • 二級緩存與一級緩存其機制相同以舒,默認也是采用 PerpetualCache,HashMap存儲慢哈,不同在于其存儲作用域為 Mapper(Namespace)蔓钟,并且可自定義存儲源,如 Ehcache卵贱。默認不打開二級緩存滥沫,要開啟二級緩存,使用二級緩存屬性類需要實現 Serializable 序列化接口(可用來保存對象的狀態(tài)),可在它的映射文件中配置<cache/> 键俱;

緩存更新

  • 進行增刪改
  • 調用清除方法
  • 設置清除屬性

MyBatis的接口綁定兰绣,以及實現方式

接口綁定:就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句進行綁定编振,我們在使用的時候直接調用接口方法即可

實現方式

  • 通過注解綁定
  • 通過xml里面寫sql語句來綁定缀辩,需要指定xml中namespace必須為接口的全路徑名。

Mybatis的mapper接口調用時有哪些要求

  • Mapper接口的方法名和mapper.xml中sql的id相同
  • Mapper 接口方法的輸入參數類型和 mapper.xml 中定義的每個 sql 的parameterType 的類型相同
  • Mapper 接口方法的輸出參數類型和 mapper.xml 中定義的每個 sql 的resultType 的類型相同
  • Mapper.xml 文件中的 namespace 即是 mapper 接口的類路徑

Mybatis 的插件運行原理踪央,以及如何編寫一個插件臀玄。

Mybatis 僅可以編寫針對 ParameterHandler、ResultSetHandler畅蹂、StatementHandler健无、Executor 這 4 種接口的插件,Mybatis 使用 JDK 的動態(tài)代理魁莉,為需要攔截的接口生成代理對象以實現接口方法攔截功能睬涧,每當執(zhí)行這 4 種接口對象的方法時募胃,就會進入攔截方法旗唁,具體就是 InvocationHandler 的 invoke()方法,當然痹束,只會攔截那些你指定需要攔截的方法检疫。

編寫插件:實現 Mybatis 的 Interceptor 接口并復寫 intercept()方法,然后在給插件編寫注解祷嘶,指定要攔截哪一個接口的哪些方法即可屎媳,記住,別忘了在配置文件中配置你編寫的插件论巍。

預編譯

定義

SQL預編譯是指數據庫驅動在發(fā)送SQL語句和參數給DBMS之前對SQL語句進行編譯烛谊,這樣DBMS執(zhí)行SQL時,就不需要重現編譯

預編譯作用

可以優(yōu)化SQL的執(zhí)行嘉汰。預編譯后的大多數SQL可以直接運行丹禀,同時預編譯語句對象可以重復利用。還可以防止SQL注入

MyBatis有哪些Executor執(zhí)行器,他們之間的區(qū)別是什么

有三種基本的Executor執(zhí)行器:SimpleExecutor双泪、ReuseExxecutor持搜、BatchExecutor

SimpleExecutor

每執(zhí)行一次update或者select就開啟一個Statement對象,用完就立即關閉

ReuseRxecutor

執(zhí)行update或者select焙矛,以sql為key查找Statement對象葫盼。為了重復使用Statement對象

BatchExecutor

執(zhí)行update,將所有sql都添加到批處理中村斟,等待同一執(zhí)行贫导。其魂村了多個Statement對象。

當實體類中的屬性名和表中的字段名不一樣蟆盹,怎么辦

  • 通過在查詢的SQL語句中定義字段名的別名脱盲,讓字段名和實體類的屬性名一致
  • 通過resultMap來映射字段名和實體類屬性名的一一對應的關系

ResultType和ResultMap的區(qū)別

首先MyBatis在查詢進行select映射的時候,返回類型可以用resultType也可以用resultMap日缨,其中resultType是直接表示返回類型的钱反,而resultMap則是對外部ResultMap的引用。這兩不能同時存在

在MyBatis進行查詢映射的時候匣距,其實查詢出來的每一個屬性都是放在一個對應的Map中面哥,鍵是屬性名、值是對應的值毅待。

最后

  • 如果覺得看完有收獲尚卫,希望能關注一下,順便給我點個贊尸红,這將會是我更新的最大動力吱涉,感謝各位的支持
  • 歡迎各位關注我的公眾號【java冢狐】,專注于java和計算機基礎知識外里,保證讓你看完有所收獲怎爵,不信你打我
  • 求一鍵三連:點贊、轉發(fā)盅蝗、在看鳖链。
  • 如果看完有不同的意見或者建議,歡迎多多評論一起交流墩莫。感謝各位的支持以及厚愛芙委。

——我是冢狐,和你一樣熱愛編程狂秦。

歡迎關注公眾號“ Java冢狐”灌侣,獲取最新消息

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市裂问,隨后出現的幾起案子侧啼,更是在濱河造成了極大的恐慌玖姑,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慨菱,死亡現場離奇詭異焰络,居然都是意外死亡,警方通過查閱死者的電腦和手機符喝,發(fā)現死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門闪彼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人协饲,你說我怎么就攤上這事畏腕。” “怎么了茉稠?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵描馅,是天一觀的道長。 經常有香客問我而线,道長铭污,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任膀篮,我火速辦了婚禮嘹狞,結果婚禮上,老公的妹妹穿的比我還像新娘誓竿。我一直安慰自己磅网,他們只是感情好,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布筷屡。 她就那樣靜靜地躺著涧偷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪毙死。 梳的紋絲不亂的頭發(fā)上燎潮,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音规哲,去河邊找鬼跟啤。 笑死诽表,一個胖子當著我的面吹牛唉锌,可吹牛的內容都是我干的。 我是一名探鬼主播竿奏,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼袄简,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泛啸?” 一聲冷哼從身側響起绿语,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吕粹,有當地人在樹林里發(fā)現了一具尸體种柑,經...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年匹耕,在試婚紗的時候發(fā)現自己被綠了聚请。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡稳其,死狀恐怖驶赏,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情既鞠,我是刑警寧澤煤傍,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站嘱蛋,受9級特大地震影響蚯姆,放射性物質發(fā)生泄漏。R本人自食惡果不足惜洒敏,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一蒋失、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桐玻,春花似錦篙挽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至偏竟,卻和暖如春煮落,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背踊谋。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工蝉仇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人殖蚕。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓轿衔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親睦疫。 傳聞我的和親對象是個殘疾皇子害驹,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內容