一、Mybatis框架流程簡介

二、梳理自己的Mybatis的設計思路

三、實現自己的Mybatis

最近研究了一下Mybatis,給大家磕叨磕叨,MyBatis框架的核心功能其實不難,無非就是動態代理和jdbc的操作,難的是寫出來可擴充套件,高內聚,低耦合的規範的程式碼。本文完成的Mybatis功能比較簡單,程式碼還有許多需要改進的地方,大家可以結合Mybatis原始碼去動手完善。

《Netty 實現原理與原始碼解析 —— 精品合集》

《Spring 實現原理與原始碼解析 —— 精品合集》

《MyBatis 實現原理與原始碼解析 —— 精品合集》

《Spring MVC 實現原理與原始碼解析 —— 精品合集》

《Spring Boot 實現原理與原始碼解析 —— 精品合集》

《資料庫實體設計合集》

《Java 面試題 —— 精品合集》

《Java 學習指南 —— 精品合集》

一、Mybatis框架流程簡介

從 0 開始手寫一個 Mybatis 框架,三步搞定!

在手寫自己的Mybatis框架之前,我們先來了解一下Mybatis,它的原始碼中使用了大量的設計模式,閱讀原始碼並觀察設計模式在其中的應用,才能夠更深入的理解原始碼。我們對上圖進行分析總結:

mybatis的配置檔案有2類

mybatisconfig。xml,配置檔案的名稱不是固定的,配置了全域性的引數的配置,全域性只能有一個配置檔案。

Mapper。xml 配置多個statemement,也就是多個sql,整個mybatis框架中可以有多個Mappe。xml配置檔案。

透過mybatis配置檔案得到SqlSessionFactory

透過SqlSessionFactory得到SqlSession,用SqlSession就可以操作資料了。

SqlSession透過底層的Executor(執行器),執行器有2類實現:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

基本實現

帶有快取功能的實現

MappedStatement是透過Mapper。xml中定義statement生成的物件。

引數輸入執行並輸出結果集,無需手動判斷引數型別和引數下標位置,且自動將結果集對映為Java物件

HashMap,KV格式的資料型別

Java的基本資料型別

POJO,java的物件

二、梳理自己的Mybatis的設計思路

根據上文Mybatis流程,我簡化了下,分為以下步驟:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

1.讀取xml檔案,建立連線

從圖中可以看出,MyConfiguration負責與人互動。待讀取xml後,將屬性和連線資料庫的操作封裝在MyConfiguration物件中供後面的元件呼叫。本文將使用dom4j來讀取xml檔案,它具有效能優異和非常方便使用的特點。

2.建立SqlSession,搭建Configuration和Executor之間的橋樑

我們經常在使用框架時看到Session,Session到底是什麼呢?一個Session僅擁有一個對應的資料庫連線。類似於一個前段請求Request,它可以直接呼叫exec(SQL)來執行SQL語句。從流程圖中的箭頭可以看出,MySqlSession的成員變數中必須得有MyExecutor和MyConfiguration去集中做調配,箭頭就像是一種關聯關係。我們自己的MySqlSession將有一個getMapper方法,然後使用動態代理生成物件後,就可以做資料庫的操作了。

3.建立Executor,封裝JDBC操作資料庫

Executor是一個執行器,負責SQL語句的生成和查詢快取(快取還沒完成)的維護,也就是jdbc的程式碼將在這裡完成,不過本文只實現了單表,有興趣的同學可以嘗試完成多表。

4.建立MapperProxy,使用動態代理生成Mapper物件

我們只是希望對指定的介面生成一個物件,使得執行它的時候能執行一句sql罷了,而介面無法直接呼叫方法,所以這裡使用動態代理生成物件,在執行時還是回到MySqlSession中呼叫查詢,最終由MyExecutor做JDBC查詢。這樣設計是為了單一職責,可擴充套件性更強。

三、實現自己的Mybatis

工程檔案及目錄:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

首先,新建一個maven專案,在pom。xml中匯入以下依賴:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

建立我們的資料庫xml配置檔案:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

然後在資料庫建立test庫,執行如下SQL語句:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

建立User實體類,和UserMapper介面和對應的xml檔案:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

基本操作配置完成,接下來我們開始實現MyConfiguration:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

從 0 開始手寫一個 Mybatis 框架,三步搞定!

從 0 開始手寫一個 Mybatis 框架,三步搞定!

從 0 開始手寫一個 Mybatis 框架,三步搞定!

用面向物件的思想設計讀取xml配置後:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

接下來實現我們的MySqlSession,首先的成員變數裡得有Excutor和MyConfiguration,程式碼的精髓就在getMapper的方法裡。

從 0 開始手寫一個 Mybatis 框架,三步搞定!

緊接著建立Executor和實現類:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

MyExecutor中封裝了JDBC的操作:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

從 0 開始手寫一個 Mybatis 框架,三步搞定!

MyMapperProxy代理類完成xml方法和真實方法對應,執行查詢:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

到這裡,就完成了自己的Mybatis框架,我們測試一下:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

執行結果:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

查詢一個不存在的使用者試試:

從 0 開始手寫一個 Mybatis 框架,三步搞定!

到這裡我們就大功告成了!