天天看點

mybatis源碼學習篇之——執行流程分析

前言

在正式學習mybatis架構源碼之前,需要先弄懂幾個問題?myabtis架構是什麼?為什麼需要mybatis架構?使用mybatis架構帶來的好處是什麼?

回答這幾個問題之前,我們先來看一下,之前在沒有架構的時候,假如使用jdbc的方式進行開發,會怎樣呢?下面來看一段使用jdbc的方式查詢資料庫的代碼吧

public class TestJdbc {

    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet resultSet = null;
        String URL = "jdbc:mysql://IP:3306/test?characterEncoding=utf-8";
        String USER = "root";
        String PASSWORD = "123456";
        try{
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(URL, USER, PASSWORD);
            String sql = "select * from user where username = ?";
            ps = connection.prepareStatement(sql);
            ps.setString(1,"zhangfei");
            resultSet = ps.executeQuery();
            while (resultSet.next()){
                System.out.println(resultSet.getInt("id") + ":" +resultSet.getString("address"));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                resultSet.close();
                ps.close();
                connection.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

}
           

這段代碼,就不用多做解釋了吧,直接運作觀察結果

mybatis源碼學習篇之——執行流程分析

讓我們來梳理一下在jdbc方式下,這個過程是怎麼完成的呢?

1、建立一個connection對象

可以認為,上面的URL,USERNAME,PASSWORD屬性都是為了建立與資料庫互動的條件,Class.forName指定了要加載的資料庫的連接配接驅動是哪種類型,這裡是mysql類型的資料庫,通過DriverManager.getConnection這一句,可以認為建立了一個與資料庫連接配接的socket通道

mybatis源碼學習篇之——執行流程分析

2、通過PreparedStatement建立預處理sql語句對象

使用PreparedStatement将外部傳入的sql進行二次處理并包裝成可執行的sql語句

mybatis源碼學習篇之——執行流程分析

3、執行sql,并擷取傳回結果

将上一步得到的PreparedStatement通過connection傳入sql執行器進行執行,得到結果集resultSet,如果擷取到了執行結果,就封裝在resultSet對象中,就可以解析resultSet

mybatis源碼學習篇之——執行流程分析

從上面的分析來看,大緻的步驟可分解為3步,建立連接配接對象,建構可執行的PreparedStatement,最後執行查詢擷取結果

其中,最關鍵的步驟想必大家都猜到了,集中在PreparedStatement這個對象的建構與執行中,這也是jdbc完成資料庫的CRUD中最核心的一個對象元件

但是我們發現,在sql語句比較簡單的情況下,通過簡單的參數拼接可以完成CRUD操作,一旦參數比較多,而且入參的方式不再是單一的參數而是對象,集合等,繼續手動拼接,這個二工作量就比較大了

得到結果集之後,還需要我們通過周遊的方式手動去解析,需要對照字段的屬性映射一一解析,當表的字段特别多的時候,這個可就比較折騰人了

綜上所述,使用原生的JDBC的方式進行開發,在使用過程中存在諸多的不友善,導緻開發人員将投入更多的時間和精力在這些瑣碎的sql拼接與結果的解析上,是以需要一種架構,可以幫助開發人員更快的解決這個問題,把精力投入到業務開發中

mybatis解決的問題

了解了jdbc的問題之後,通過mybatis架構的使用,至少可以解決如下幾個使用中的問題

  • 與JDBC相比,降低了至少一倍以上的代碼量
  • 靈活,不會對應用程式或者資料庫的現有設計強加任何影響,SQL寫在XML裡,從程式代碼中徹底分離,降低耦合度,便于統一管理和優化,可重用
  • 提供XML标簽,支援編寫動态SQL語句(XML中使用if, else等)
  • 提供映射标簽,支援對象與資料庫的ORM字段關系映射(在XML中配置映射關系,也可以使用注解)

執行流程

從大的方面,将mybatis的執行流程圖總結如下:

mybatis源碼學習篇之——執行流程分析

1、mybatis配置檔案

  • SqlMapConfig.xml,此檔案作為mybatis的全局配置檔案,配置了mybatis

    的運作環境等資訊

  • Mapper.xml,此檔案作為mybatis的sql映射檔案,檔案中配置了操作資料

    庫的sql語句。此檔案需要在SqlMapConfig.xml中加載

2、 SqlSessionFactory

通過mybatis環境等配置資訊構造SqlSessionFactory,即會話工廠

3、sqlSession

通過會話工廠建立sqlSession即會話,程式員通過sqlsession會話接口對資料庫

進行增删改查操作

4、 Executor執行器

mybatis底層自定義了Executor執行器接口來具體操作資料庫,Executor接口有

兩個實作,一個是基本執行器(預設)、一個是緩存執行器,sqlsession底層是

通過executor接口操作資料庫的

5、Mapped Statement

它是mybatis一個底層封裝對象,它包裝了mybatis配置資訊及sql映射資訊等。mapper.xml檔案中一個select\insert\update\delete标簽對應一個Mapped Statement對象,select\insert\update\delete标簽的id即是Mappedstatement的id

  • Mapped Statement對sql執行輸入參數進行定義,包括HashMap、基本類型、

    pojo,Executor通過Mapped Statement在執行sql前将輸入的java對象映射至sql

    中,輸入參數映射就是jdbc程式設計中對preparedStatement設定參數

  • Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本類型、

    pojo,Executor通過Mapped Statement在執行sql後将輸出結果映射至java對象

    中,輸出結果映射過程相當于jdbc程式設計中對結果的解析處理過程

調用過程流程圖

mybatis源碼學習篇之——執行流程分析

SqlSession

接收開發人員提供Statement Id 和參數.并傳回操作結果

Executor

MyBatis執行器,是MyBatis 排程的核心,負責SQL語句的生成和查詢緩存的維護

StatementHandler

封裝了JDBC Statement操作,負責對JDBC statement 的操作,如設定參數、将Statement結果集轉換成List集合

ParameterHandler

負責對使用者傳遞的參數轉換成JDBC Statement 所需要的參數

ResultSetHandler

負責将JDBC傳回的ResultSet結果集對象轉換成List類型的集合

TypeHandler

負責java資料類型和jdbc資料類型之間的映射和轉換

MappedStatement

維護了一條<select|update|delete|insert>節點的封裝

SqlSource

負責根據使用者傳遞的parameterObject,動态地生成SQL語句,将資訊封裝到

BoundSql對象中,并傳回BoundSql表示動态生成的SQL語句以及相應的參數資訊

Configuration

MyBatis所有的配置資訊都維持在Configuration對象之中。

通過上面的執行流程圖,以及執行過程中涉及到的各個元件作用,我們可以大緻想象一下mybatis的執行一條sql查詢時的完整鍊路,再具體點我們可以總結為如下這幅圖,

mybatis源碼學習篇之——執行流程分析

從代碼層面的結構上進行剖析,可以将整個執行過程分為3步

  1. 解析配置檔案,包括SqlMapConfig.xml以及與業務相關的xml檔案
  2. 将解析好的配置檔案,如屬性映射,連接配接資料庫資訊等封裝到Configuration對象
  3. 執行器執行CRUD并傳回結果

當然,從上面的流程圖上看,遠比這3步要複雜,因為mybatis完成并了JDBC本身的功能同時,還進行了更深入的拓展,比如結果集的自動映射,動态sql語句等,而這些過程的執行,需要更多的元件共同配合完成,才有了上述衆多的元件,下一篇我們通過源碼的方式對其中的主要元件進行分析說明

本篇到此結束,最後感謝觀看!

繼續閱讀