MyBatis常見面試題:說說MyBatis的工作原理


  本文轉自參考文獻3。

  SSM風靡當前的Java世界,面試官不經意間就會甩出一道必殺題:請你說一下MyBatis的工作原理。雖然大家每天都在使用MyBatis做增刪改查的工作,但是面對這個問題往往也得需要好好的准備一下,才能應對自如。看了很多網上的總結,都是只見樹木不見森林,可見這些人的水平和見識尚淺,道行和修為還有待提升。

  MyBatis的基本工作原理就是:先封裝SQL,接着調用JDBC操作數據庫,最后把數據庫返回的表結果封裝成Java類。

如何掌握MyBatis的工作原理

  首先我們要清楚JDBC的開發流程,見這篇文章《MyBatis的前世:JDBC數據庫編程》。我們知道,JDBC有四個核心對象:
(1)DriverManager,用於注冊數據庫連接
(2)Connection,與數據庫連接對象
(3)Statement/PrepareStatement,操作數據庫SQL語句的對象
(4)ResultSet,結果集或一張虛擬表

而MyBatis也有四大核心對象:
(1)SqlSession對象,該對象中包含了執行SQL語句的所有方法。類似於JDBC里面的Connection。
(2)Executor接口,它將根據SqlSession傳遞的參數動態地生成需要執行的SQL語句,同時負責查詢緩存的維護。類似於JDBC里面的Statement/PrepareStatement。
(3)MappedStatement對象,該對象是對映射SQL的封裝,用於存儲要映射的SQL語句的id、參數等信息。
(4)ResultHandler對象,用於對返回的結果進行處理,最終得到自己想要的數據格式或類型。可以自定義返回類型。

  根據這四大核心對象,我們就能理清MyBatis的工作原理。

MyBatis的工作原理以及核心流程詳解

  MyBatis的工作原理如下圖所示:

  上面中流程就是MyBatis內部核心流程,每一步流程的詳細說明如下文所述:

(1)讀取MyBatis的配置文件。mybatis-config.xml為MyBatis的全局配置文件,用於配置數據庫連接信息。

(2)加載映射文件。映射文件即SQL映射文件,該文件中配置了操作數據庫的SQL語句,需要在MyBatis配置文件mybatis-config.xml中加載。mybatis-config.xml 文件可以加載多個映射文件,每個文件對應數據庫中的一張表。

(3)構造會話工廠。通過MyBatis的環境配置信息構建會話工廠SqlSessionFactory。

(4)創建會話對象。由會話工廠創建SqlSession對象,該對象中包含了執行SQL語句的所有方法。

(5)Executor執行器。MyBatis底層定義了一個Executor接口來操作數據庫,它將根據SqlSession傳遞的參數動態地生成需要執行的SQL語句,同時負責查詢緩存的維護。

(6)MappedStatement對象。在Executor接口的執行方法中有一個MappedStatement類型的參數,該參數是對映射信息的封裝,用於存儲要映射的SQL語句的id、參數等信息。

(7)輸入參數映射。輸入參數類型可以是Map、List等集合類型,也可以是基本數據類型和POJO類型。輸入參數映射過程類似於JDBC對preparedStatement對象設置參數的過程。

(8)輸出結果映射。輸出結果類型可以是Map、List等集合類型,也可以是基本數據類型和POJO類型。輸出結果映射過程類似於JDBC對結果集的解析過程。

備注

  在JDBC中,Connection不直接執行SQL方法,而是利用Statement或者PrepareStatement來執行方法。在使用JDBC建立了連接之后,可以使用Connection接口的createStatement()方法來獲取Statement對象,也可以調用prepareStatement()方法獲得PrepareStatement對象,通過executeUpdate()方法來執行SQL語句。

  而在MyBatis中,SqlSession對象包含了執行SQL語句的所有方法。但是它是委托Executor執行的。從某種意義上來看,MyBatis里面的SqlSession類似於JDBC中的Connection,它們都是委托給其它類去執行。

  最后說一點,雖然SqlSession對象包含了執行SQL語句的所有方法,但是它同樣包括了:

T getMapper(Class type);

所以SqlSession也可以委托給映射器來執行數據的增刪改查操作。如下代碼所示:

// 獲得mapper接口的代理對象
PersonMapper pm = session.getMapper(PersonMapper.class);
// 直接調用接口的方法,查詢id為1的Peson數據
Person p2 = pm.selectPersonById(1);

這上面來看,SqlSession是不是也類似於JDBC中的Connection呢?

Reference


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM