面試題-MyBatis框架
前言
MyBatis框架部分的題目,是我根據Java Guide的面試突擊版本V3.0再整理出來的,其中,我選擇了一些比較重要的問題,並重新做出相應回答,並添加了一些比較重要的問題,希望對大家起到一定的幫助。
系列文章:
MyBatis
-
{}和${}的區別是什麼?
- ${}屬於靜態文字替換,可以寫在標籤的屬性值和sql內部
-
{}是sql中的引數佔位符,mybatis會把它替換成?執行sql的時候會使用PreparedStatement設定引數的方法按序給問號設定值。
-
最佳實踐中,通常⼀個 Xml 對映⽂件,都會寫⼀個 Dao 接⼝與之對應,請
問,這個 Dao 接⼝的⼯作原理是什麼?Dao 接⼝⾥的⽅法,引數不同時,⽅法能重
載嗎?介面的全限定名,就是xml檔案的namespace;介面的方法名,就是標籤中的id的值;介面的引數,就是傳遞給SQL的引數。當呼叫介面方法時,就能唯一確定到一個MappedStatement。
因為是通過全限定名+方法名找SQL的,所以DAO中的方法不支援過載
工作原理其實就是JDK動態代理,執行時實時建立代理物件,在代理方法中執行SQL查詢然後返回資料。
-
Mybatis 是如何進⾏分⻚的?分⻚外掛的原理是什麼?
MyBatis中可以使用RowBounds進行邏輯分頁,它是基於結果集的記憶體分頁,如果想實現物理分頁,可以在sql語句中實現,或者使用MyBatis的分頁外掛。分頁外掛的原理是根據方言重寫SQL。
我們專案在實際使用中使用的是PageHelper進行分頁,PageHelper的原理其實也是實現了mybatis的外掛介面,在介面中實現自己的邏輯。
-
Mybatis插入單條資料時,如何返回主鍵?
- 如果要返回自增主鍵
- 可以使用insert屬性的useGenerateKeys和keyProperty指定物件屬性即可,這裡用法的底層原理就是使用select LAST_INSERT_ID();
- 可以使用
標籤即可,標籤中使用after和select LAST_INSERT_ID();來返回自增主鍵
- 如果要返回非自增主鍵
- 可以使用
標籤即可,標籤中使用before和select uuid();來返回主鍵
- 可以使用
- 如果要返回自增主鍵
-
MyBatis批量插入時,如何返回自增主鍵?
和單條插入是類似的。
-
Mybatis 動態 sql 是做什麼的?都有哪些動態 sql?能簡述⼀下動態 sql 的執⾏原理不?
MyBatis提供了9種動態SQL標籤,動態SQL的原理主要是通過OGNL表示式計算表示式的值,根據表示式的值來動態拼接SQL。
實際專案中,我們最常用的就是where和if標籤,可以用在列表的不定條件查詢的SQL中;如果有批量插入,也會使用foreach標籤。trim標籤也可以去除多餘的and和多餘的逗號。
-
Mybatis 是如何將 sql 執⾏結果封裝為⽬標物件並返回的?都有哪些對映形式?
- resultType:除了map以外,其他的情況需要保證列名和物件屬性的對映正確,做法有兩種:1. 修改欄位別名為物件的屬性名:resultType="類名";2. 不修改別名,增加一個屬性
mapUnderscoreToCamelCase
配合resultType="類名";使用也可以- 可以返回單個物件
- 可以返回單條資料的map,resultType="map"
- 可以返回物件集合,resultType="類名"
- 可以返回多條資料的map<Key,類名>,需要在介面中指定@MapKey("lastName")註解
- resultMap,逐一定義列名和屬性名的對映關係
- resultType:除了map以外,其他的情況需要保證列名和物件屬性的對映正確,做法有兩種:1. 修改欄位別名為物件的屬性名:resultType="類名";2. 不修改別名,增加一個屬性
-
Mybatis 能執⾏⼀對⼀、⼀對多的關聯查詢嗎?都有哪些實現⽅式,以及它們之間的區別?
待完成...
-
Mybatis 是否⽀持延遲載入?如果⽀持,它的實現原理是什麼?
支援,可以配置lazyLoadingEnabled=true|false來實現延遲載入。
Mybatis僅支援association和collection的延遲載入,延遲載入的原理是,當實際使用到需要延遲載入的屬性時,發現為null,然後會去執行SQL把物件查詢出來,然後設定屬性值。
-
Mybatis 的 Xml 對映⽂件中,不同的 Xml 對映⽂件,id 是否可以重複?
不同的XML對映檔案,如果配置了namespace,那麼id可以重複,如果沒有使用namespace,那麼id不可以重複。原因是MyBatis把每一個sql語句儲存在一個map中,map中的key就是namespace+id,如果key重複,那麼就會相互覆蓋。
-
Mybatis 對映⽂件中,如果 A 標籤通過 include 引⽤了 B 標籤的內容,請問,B 標籤能否定義在 A 標籤的後⾯,還是說必須定義在 A 標籤的前⾯?
可以定義在任何地方。MyBatis解析的時候,如果發現沒有B標籤,那麼會跳過A標籤標記為未解析,等到全部解析完畢後,再重新解析一遍未解析的標籤,這個時候就可以成功了。
-
簡述 Mybatis 的 Xml 對映⽂件和 Mybatis 內部資料結構之間的對映關係?
MyBatis將所有的配置資訊都儲存在一個Configuration物件中。其中:
- parameterMap會被解析為ParameterMap物件,每個子元素被解析為ParameterMapping物件
- resultMap會被解析為ResultMap物件,每個子元素被解析為ResultMapping物件
- 增刪改查標籤被解析為MappedStatement物件
- 標籤內的sql被解析為BoundSql物件
-
為什麼說 Mybatis 是半⾃動 ORM 對映⼯具?它與全⾃動的區別在哪⾥?
待完成...