Mybatis 架構與原理

MyBatis 功能架構設計

功能架構講解:

我們把 Mybatis 的功能架構分爲三層:

(1)API 接口層:提供給外部使用的接口 API,開發人員通過這些本地 API 來操縱數據庫。接口層一接收到調用請求就會調用數據處理層來完成具體的數據處理。

(2) 數據處理層:負責具體的 SQL 查找、SQL 解析、SQL 執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次數據庫操作。

(3) 基礎支撐層:負責最基礎的功能支撐,包括連接管理、事務管理、配置加載和緩存處理,這些都是共用的東西,將他們抽取出來作爲最基礎的組件。爲上層的數據處理層提供最基礎的支撐。

框架架構

框架架構講解:

這張圖從上往下看。MyBatis 的初始化,會從 mybatis-config.xml 配置文件,解析構造成 Configuration 這個類,就是圖中的紅框。

(1) 加載配置:配置來源於兩個地方,一處是配置文件,一處是 Java 代碼的註解,將 SQL 的配置信息加載成爲一個個 MappedStatement 對象(包括了傳入參數映射配置、執行的 SQL 語句、結果映射配置),存儲在內存中。

(2)SQL 解析:當 API 接口層接收到調用請求時,會接收到傳入 SQL 的 ID 和傳入對象(可以是 Map、JavaBean 或者基本數據類型),Mybatis 會根據 SQL 的 ID 找到對應的 MappedStatement,然後根據傳入參數對象對 MappedStatement 進行解析,解析後可以得到最終要執行的 SQL 語句和參數。

(3)SQL 執行:將最終得到的 SQL 和參數拿到數據庫進行執行,得到操作數據庫的結果。

(4) 結果映射:將操作數據庫的結果按照映射的配置進行轉換,可以轉換成 HashMap、JavaBean 或者基本數據類型,並將最終結果返回。

MyBatis 核心類

1、SqlSessionFactoryBuilder

每一個 MyBatis 的應用程序的入口是 SqlSessionFactoryBuilder。

它的作用是通過 XML 配置文件創建 Configuration 對象(當然也可以在程序中自行創建),然後通過 build 方法創建 SqlSessionFactory 對象。沒有必要每次訪問 Mybatis 就創建一次 SqlSessionFactoryBuilder,通常的做法是創建一個全局的對象就可以了。示例程序如下:

private static SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
private static SqlSessionFactory sqlSessionFactory;

private static void init() throws IOException {
    String resource = "mybatis-config.xml";
    Reader reader = Resources.getResourceAsReader(resource);
    sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    sqlSessionFactory = sqlSessionFactoryBuilder.build(reader);
}

org.apache.ibatis.session.Configuration 是mybatis初始化的核心。

mybatis-config.xml 中的配置,最後會解析 xml 成 Configuration 這個類。

SqlSessionFactoryBuilder 根據傳入的數據流 (XML) 生成 Configuration 對象,然後根據 Configuration 對象創建默認的 SqlSessionFactory 實例。

2、SqlSessionFactory 對象由 SqlSessionFactoryBuilder 創建:

它的主要功能是創建 SqlSession 對象,和 SqlSessionFactoryBuilder 對象一樣,沒有必要每次訪問 Mybatis 就創建一次 SqlSessionFactory,通常的做法是創建一個全局的對象就可以了。SqlSessionFactory 對象一個必要的屬性是 Configuration 對象,它是保存 Mybatis 全局配置的一個配置對象,通常由 SqlSessionFactoryBuilder 從 XML 配置文件創建。這裏給出一個簡單的示例:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC 
   "-//mybatis.org//DTD Config 3.0//EN"
   "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <!-- 配置別名 -->
   <typeAliases>
       <typeAlias type="org.iMybatis.abc.dao.UserDao" alias="UserDao" />
       <typeAlias type="org.iMybatis.abc.dto.UserDto" alias="UserDto" />
   </typeAliases>
    
   <!-- 配置環境變量 -->
   <environments default="development">
       <environment>
           <transactionManager type="JDBC" />
           <dataSource type="POOLED">
               <property  />
               <property jdbc:mysql://127.0.0.1:3306/iMybatis?characterEncoding=GBK" />
               <property  />
               <property  />
           </dataSource>
       </environment>
   </environments>
   
   <!-- 配置mappers -->
   <mappers>
       <mapper resource="org/iMybatis/abc/dao/UserDao.xml" />
   </mappers>
   
</configuration>
3、SqlSession

SqlSession 對象的主要功能是完成一次數據庫的訪問和結果的映射,它類似於數據庫的 session 概念,由於不是線程安全的,所以 SqlSession 對象的作用域需限制方法內。SqlSession 的默認實現類是 DefaultSqlSession,它有兩個必須配置的屬性:Configuration 和 Executor。Configuration 前文已經描述這裏不再多說。SqlSession 對數據庫的操作都是通過 Executor 來完成的。

SqlSession :默認創建 DefaultSqlSession 並且開啓一級緩存,創建執行器 、賦值。

SqlSession 有一個重要的方法 getMapper,顧名思義,這個方式是用來獲取 Mapper 對象的。什麼是 Mapper 對象?根據 Mybatis 的官方手冊,應用程序除了要初始並啓動 Mybatis 之外,還需要定義一些接口,接口裏定義訪問數據庫的方法,存放接口的包路徑下需要放置同名的 XML 配置文件。

SqlSession 的 getMapper 方法是聯繫應用程序和 Mybatis 紐帶,應用程序訪問 getMapper 時,Mybatis 會根據傳入的接口類型和對應的 XML 配置文件生成一個代理對象,這個代理對象就叫 Mapper 對象。應用程序獲得 Mapper 對象後,就應該通過這個 Mapper 對象來訪問 Mybatis 的 SqlSession 對象,這樣就達到裏插入到 Mybatis 流程的目的。

SqlSession session= sqlSessionFactory.openSession();  
UserDao userDao = session.getMapper(UserDao.class);  
UserDto user = new UserDto();  
user.setUsername("iMybatis");  
List<UserDto> users = userDao.queryUsers(user);  

public interface UserDao {
    public List<UserDto> queryUsers(UserDto user) throws Exception;
}

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
<mapper namespace="org.iMybatis.abc.dao.UserDao">  
    <select parameterType="UserDto" resultType="UserDto"  
        useCache="false">  
        <![CDATA[ 
        select * from t_user t where t.username = #{username} 
        ]]>  
    </select>  
</mapper>
4、Executor

Executor 對象在創建 Configuration 對象的時候創建,並且緩存在 Configuration 對象裏。Executor 對象的主要功能是調用 StatementHandler 訪問數據庫,並將查詢結果存入緩存中(如果配置了緩存的話)。

5、StatementHandler

StatementHandler 是真正訪問數據庫的地方,並調用 ResultSetHandler 處理查詢結果。

6、ResultSetHandler

處理查詢結果。

MyBatis 成員層次 & 職責

  1. SqlSession 作爲 MyBatis 工作的主要頂層 API,表示和數據庫交互的會話,完成必要數據庫增刪改查功能
  2. Executor MyBatis 執行器,是 MyBatis 調度的核心,負責 SQL 語句的生成和查詢緩存的維護
  3. StatementHandler 封裝了 JDBC Statement 操作,負責對 JDBCstatement 的操作,如設置參數、將 Statement 結果集轉換成 List 集合。
  4. ParameterHandler 負責對用戶傳遞的參數轉換成 JDBC Statement 所需要的參數
  5. ResultSetHandler * 負責將 JDBC 返回的 ResultSet 結果集對象轉換成 List 類型的集合;
  6. TypeHandler 負責 java 數據類型和 jdbc 數據類型之間的映射和轉換
  7. MappedStatement MappedStatement 維護了一條 <select|update|delete|insert> 節點的封
  8. SqlSource 負責根據用戶傳遞的 parameterObject,動態地生成 SQL 語句,將信息封裝到 BoundSql 對象中,並返回
  9. BoundSql 表示動態生成的 SQL 語句以及相應的參數信息
  10. Configuration MyBatis 所有的配置信息都維持在 Configuration 對象之中
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://www.jianshu.com/p/15781ec742f2