好程式設計師Java培訓分享Mybatis面試題集合

好程式設計師發表於2020-10-12

  今天好程式設計師Java 培訓老師給大家分享一篇關於 Mybatis 面試題的詳細介紹,下面我們一起來看一下吧。

  1.#{} ${} 的區別是什麼?

  #{} 是預編譯處理, ${} 是字串替換。

  Mybatis 在處理 #{} 時,會將 sql 中的 #{} 替換為 ? 號,呼叫 PreparedStatement set 方法來賦值;

  Mybatis 在處理 ${} 時,就是把 ${} 替換成變數的值。

  使用#{} 可以有效的防止 SQL 注入,提高系統安全性。

  2. 通常一個 Xml 對映檔案,都會寫一個 Dao 介面與之對應,請問,這個 Dao 介面的工作原理是什麼? Dao 介面裡的方法,引數不同時,方法能過載嗎?

  Dao 介面,就是人們常說的 Mapper 介面,介面的全限名,就是對映檔案中的 namespace 的值,介面的方法名,就是對映檔案中 MappedStatement id 值,介面方法內的引數,就是傳遞給 sql 的引數。

  Mapper 介面是沒有實現類的,當呼叫介面方法時,介面全限名 + 方法名拼接字串作為 key 值,可唯一定位一個 MappedStatement ,舉例: com.mybatis3.mappers.StudentDao.findStudentById ,可以唯一找到 namespace com.mybatis3.mappers.StudentDao 下面 id=findStudentById MappedStatement 。在 Mybatis 中,每一個 <select> <insert> <update> <delete> 標籤,都會被解析為一個 MappedStatement 物件。

  Dao 介面裡的方法,是不能過載的,因為是全限名 + 方法名的儲存和尋找策略。

  Dao 介面的工作原理是 JDK 動態代理, Mybatis 執行時會使用 JDK 動態代理為 Dao 介面生成代理 proxy 物件,代理物件 proxy 會攔截介面方法,轉而執行 MappedStatement 所代表的 sql ,然後將 sql 執行結果返回。

  3.Mybatis 是如何進行分頁的?分頁外掛的原理是什麼?

  Mybatis 使用 RowBounds 物件進行分頁,它是針對 ResultSet 結果集執行的記憶體分頁,而非物理分頁,可以在 sql 內直接書寫帶有物理分頁的引數來完成物理分頁功能,也可以使用分頁外掛來完成物理分頁。

  分頁外掛的基本原理是使用Mybatis 提供的外掛介面,實現自定義外掛,在外掛的攔截方法內攔截待執行的 sql ,然後重寫 sql ,根據 dialect 方言,新增對應的物理分頁語句和物理分頁引數。

  4.Mybatis 是如何將 sql 執行結果封裝為目標物件並返回的?都有哪些對映形式?

  第一種是使用<resultMap> 標籤,逐一定義列名和物件屬性名之間的對映關係。

  第二種是使用sql 列的別名功能,將列別名書寫為物件屬性名,比如 T_NAMEASNAME ,物件屬性名一般是 name ,小寫,但是列名不區分大小寫, Mybatis 會忽略列名大小寫,智慧找到與之對應物件屬性名,你甚至可以寫成 T_NAMEASNaMe Mybatis 一樣可以正常工作。

  有了列名與屬性名的對映關係後,Mybatis 透過反射建立物件,同時使用反射給物件的屬性逐一賦值並返回,那些找不到對映關係的屬性,是無法完成賦值的。

  5.Xml 對映檔案中,除了常見的 select|insert|update|delete 標籤之外,還有哪些標籤?

  還有很多其他的標籤,加上動態sql 9 個標籤, trim|where|set|foreach|if|choose|when|otherwise|bind 等,其中為 sql 片段標籤,透過標籤引入 sql 片段,為不支援自增的主鍵生成策略標籤。

  6. 簡述 Mybatis 的外掛執行原理,以及如何編寫一個外掛?

  Mybatis 僅可以編寫針對 ParameterHandler ResultSetHandler StatementHandler Executor 4 種介面的外掛, Mybatis 使用 JDK 的動態代理,為需要攔截的介面生成代理物件以實現介面方法攔截功能,每當執行這 4 種介面物件的方法時,就會進入攔截方法,具體就是 InvocationHandler invoke() 方法,當然,只會攔截那些你指定需要攔截的方法。實現 Mybatis Interceptor 介面並複寫 intercept() 方法,然後在給外掛編寫註解,指定要攔截哪一個介面的哪些方法即可,記住,還需要在配置檔案中配置你編寫的外掛。

  7. 一級、二級快取

  1 )一級快取 : 基於 PerpetualCache HashMap 本地快取,其儲存作用域為 Session ,當 Sessionflush close 之後,該 Session 中的所有 Cache 就將清空。

  2 )二級快取與一級快取其機制相同,預設也是採用 PerpetualCache HashMap 儲存,不同在於其儲存作用域為 Mapper(Namespace) ,並且可自定義儲存源,如 Ehcache 。要開啟二級快取,你需要在你的 SQL 對映檔案中新增一行: <cache/>

  3 )對於快取資料更新機制,當某一個作用域 ( 一級快取 Session/ 二級快取 Namespaces) 的進行了 C/U/D 操作後,預設該作用域下所有 select 中的快取將被 clear

  8.Mybatis 是否支援延遲載入?如果支援,它的實現原理是什麼?

  Mybatis 僅支援 association 關聯物件和 collection 關聯集合物件的延遲載入, association 指的就是一對一, collection 指的就是一對多查詢。在 Mybatis 配置檔案中,可以配置是否啟用延遲載入 lazyLoadingEnabled=true|false

  它的原理是,使用CGLIB 建立目標物件的代理物件,當呼叫目標方法時,進入攔截器方法,比如呼叫 a.getB().getName() ,攔截器 invoke() 方法發現 a.getB() null 值,那麼就會單獨傳送事先儲存好的查詢關聯 B 物件的 sql ,把 B 查詢上來,然後呼叫 a.setB(b) ,於是 a 的物件 b 屬性就有值了,接著完成 a.getB().getName() 方法的呼叫。這就是延遲載入的基本原理。

  9.Mybatis 對映檔案中,如果 A 標籤透過 include 引用了 B 標籤的內容,請問, B 標籤能否定義在 A 標籤的後面,還是說必須定義在 A 標籤的前面?

  雖然Mybatis 解析 Xml 對映檔案是按照順序解析的,但是,被引用的 B 標籤依然可以定義在任何地方, Mybatis 都可以正確識別。

  原理是,Mybatis 解析 A 標籤,發現 A 標籤引用了 B 標籤,但是 B 標籤尚未解析到,尚不存在,此時, Mybatis 會將 A 標籤標記為未解析狀態,然後繼續解析餘下的標籤,包含 B 標籤,待所有標籤解析完畢, Mybatis 會重新解析那些被標記為未解析的標籤,此時再解析 A 標籤時, B 標籤已經存在, A 標籤也就可以正常解析完成了。

  10. 簡述 Mybatis Xml 對映檔案和 Mybatis 內部資料結構之間的對映關係?

  Mybatis 將所有 Xml 配置資訊都封裝到 All-In-One 重量級物件 Configuration 內部。在 Xml 對映檔案中, <parameterMap> 標籤會被解析為 ParameterMap 物件,其每個子元素會被解析為 ParameterMapping 物件。 <resultMap> 標籤會被解析為 ResultMap 物件,其每個子元素會被解析為 ResultMapping 物件。每一個 <select> <insert> <update> <delete> 標籤均會被解析為 MappedStatement 物件,標籤內的 sql 會被解析為 BoundSql 物件。

  11 、簡述 Mybatis 的外掛執行原理,以及如何編寫一個外掛。

  Mybatis 僅可以編寫針對 ParameterHandler ResultSetHandler StatementHandler Executor 4 種介面的外掛, Mybatis 使用 JDK 的動態代理,為需要攔截的介面生成代理物件以實現介面方法攔截功能,每當執行這 4 種介面物件的方法時,就會進入攔截方法,具體就是 InvocationHandler invoke() 方法,當然,只會攔截那些你指定需要攔截的方法。

  實現Mybatis Interceptor 介面並複寫 intercept() 方法,然後在給外掛編寫註解,指定要攔截哪一個介面的哪些方法即可,記住,別忘了在配置檔案中配置你編寫的外掛。

  12 Mybatis 動態 sql 是做什麼的?都有哪些動態 sql ?能簡述一下動態 sql 的執行原理不?

  Mybatis 動態 sql 可以讓我們在 Xml 對映檔案內,以標籤的形式編寫動態 sql ,完成邏輯判斷和動態拼接 sql 的功能, Mybatis 提供了 9 種動態 sql 標籤 trim|where|set|foreach|if|choose|when|otherwise|bind

  其執行原理為,使用OGNL sql 引數物件中計算表示式的值,根據表示式的值動態拼接 sql ,以此來完成動態 sql 的功能。

  13 Mybatis Xml 對映檔案中,不同的 Xml 對映檔案, id 是否可以重複?

  不同的xml 對映檔案,如果配置了 namespace ,那麼 id 可以重複;如果沒有配置 namespace ,那麼 id 不能重複;畢竟 namespace 不是必須的,只是最佳實踐而已。

  原因就是namespace+id 是作為 Map

  14 MyBatis(IBatis) 的好處是什麼

  ibatis sql 語句從 Java 源程式中獨立出來,放在單獨的 XML 檔案中編寫,給程式的維護帶來了很大便利。 ibatis 封裝了底層 JDBCAPI 的呼叫細節,並能自動將結果集轉換成 JavaBean 物件,大大簡化了 Java 資料庫程式設計的重複工作。因為 Ibatis 需要程式設計師自己去編寫 sql 語句,程式設計師可以結合資料庫自身的特點靈活控制 sql 語句,因此能夠實現比 hibernate 等全自動 orm 框架更高的查詢效率,能夠完成複雜查詢 .

  15 、什麼情況下用註解繫結 , 什麼情況下用 xml 繫結?

  當Sql 語句比較簡單時候 , 用註解繫結 ,

  當SQL 語句比較複雜時候 , xml 繫結 , 一般用 xml 繫結的比較多

  16 MyBatis 實現一對多有幾種方式 , 怎麼操作的?

  有聯合查詢和巢狀查詢, 聯合查詢是幾個表聯合查詢 , 只查詢一次 , 透過在 resultMap 裡面配置 collection 節點配置一對多的類就可以完成 ;

  巢狀查詢是先查一個表, 根據這個表裡面的結果的外來鍵 id, 去再另外一個表裡面查詢資料 , 也是透過配置 collection, 但另外一個表的查詢透過 select 節點配置。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913864/viewspace-2726364/,如需轉載,請註明出處,否則將追究法律責任。

相關文章