Mybatis原始碼分析(一)Mybatis的架構設計簡介

清幽之地發表於2019-03-10

一、前言

擼完Spring框架,我們接著下一個征程,Mybatis。相對Spring而言,Mybatis就顯得短小精悍。在本系列原始碼開始之前,我們先來一起了解下Mybatis的相關知識點。

二、什麼是 MyBatis ?

MyBatis 是一款優秀的持久層框架,它支援定製化 SQL、儲存過程以及高階對映。MyBatis 避免了幾乎所有的 JDBC 程式碼和手動設定引數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置和對映原生資訊,將介面和 Java 的 POJOs(Plain Old Java Objects,普通的 Java物件)對映成資料庫中的記錄。

三、架構

Mybatis架構

1、介面層

介面層主要定義的是與資料庫進行互動的方式。在Mybatis中,互動分為兩種方式。

  • Mybatis提供的API

使用Mybatis提供的API進行操作,通過獲取SqlSession物件,然後根據Statement Id 和引數來運算元據庫。

String statement = "com.viewscenes.netsupervisor.dao.UserMapper.getUserList";
List<User> result = sqlsession.selectList(statement);
複製程式碼
  • 使用Mapper介面

事實上這個才是經常使用的方式,面向介面程式設計嘛。每一個Mapper介面中的方法對應著mapper.xml檔案中的一個select/insert/update/delete節點。節點中的ID就是介面中的方法名,在使用的時候直接呼叫介面方法即可。不過,值得注意的是,它最終執行的還是sqlSession.select()、sqlSession.delete()

2、資料處理層

這是Mybatis的核心。它負責引數對映和動態SQL生成,生成之後Mybatis執行SQL語句,並將返回的結果對映成自定義的型別。關於引數對映和結果集轉換,主要是靠typeHandlers。為便於理解,我們大概來看幾個型別處理器。

型別處理器 Java型別 JDBC型別
StringTypeHandler java.lang.String CHAR, VARCHAR
DateTypeHandler java.util.Date TIMESTAMP
BooleanTypeHandler java.lang.Boolean, boolean 資料庫相容的 BOOLEAN
IntegerTypeHandler java.lang.Integer, int 資料庫相容的 NUMERIC 或 INTEGER

3、框架支撐層

  • 事務管理

對於ORM框架而言,事務管理是必不可少的一部分。不過,一般情況下,Mybatis都是和Spring搭配使用的,更多的是用Spring來接管事務管理。

  • 連線池

我們不能每次在執行SQL的時候才去建立資料庫的連線。因為建立連線是一個相對比較耗時的操作,通常做法是用一個列表儲存提前建立好的N個連線,用到的時候去拿,用完再還回去。關於資料庫連線池,業界有很多開源實現。比如C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等。

  • 快取

為了提高資料利用率和減小伺服器和資料庫的壓力,Mybatis 會對於一些查詢提供會話級別的資料快取,會將對某一次查詢,放置到SqlSession 中,在允許的時間間隔內,對於完全相同的查詢,MyBatis 會直接將快取結果返回給使用者,而不用再到資料庫中查詢。

一級快取是SqlSession級別的快取,在同一個sqlSession中兩次執行相同的sql語句,第一次執行完畢會將資料庫中查詢的資料寫到快取(記憶體),第二次會從快取中獲取資料將不再從資料庫查詢,從而提高查詢效率,Mybtais預設開啟一級快取。

二級快取是mapper級別的快取,多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession去運算元據庫得到資料會存在二級快取區域,多個SqlSession可以共用二級快取,二級快取是跨SqlSession的。要開啟二級快取,需要在你的 SQL 對映檔案中新增一行:。它會將所有的select語句快取,在執行insert,update 和 delete 語句時會重新整理快取,快取根據LRU演算法來回收。

4、SQL配置方式

大部分時候我們都是通過XML方式來配置SQL,不過Mybatis也支援通過註解來配置,就像下面這樣。

@Select({"<script>", "select * from user"
		"</script>"})
List<ConsultContent> getUserList();
複製程式碼

不過,不推薦這種方式來搞,除非你想挖坑....想想吧,一個複雜的SQL,幾十行上百行,寫時一時爽,維護滿面淚。

5、引導層

引導層是配置和啟動MyBatis 配置資訊的方式。MyBatis 提供兩種方式來引導MyBatis :基於XML配置檔案的方式和基於Java API 的方式。

四、主要構件

  • SqlSession 作為MyBatis工作的主要頂層API,表示和資料庫互動的會話,完成必要資料庫增刪改查功能。

  • Executor MyBatis執行器,是MyBatis 排程的核心,負責SQL語句的生成和查詢快取的維護。

  • StatementHandler   封裝了JDBC Statement操作,負責對JDBC statement 的操作,如設定引數、將Statement結果集轉換成List集合。

  • ParameterHandler   負責對使用者傳遞的引數轉換成JDBC Statement 所需要的引數。

  • ResultSetHandler    負責將JDBC返回的ResultSet結果集物件轉換成List型別的集合。

  • TypeHandler          負責java資料型別和jdbc資料型別之間的對映和轉換。

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

  • SqlSource            負責根據使用者傳遞的parameterObject,動態地生成SQL語句,將資訊封裝到BoundSql物件中,並返回。

  • BoundSql             表示動態生成的SQL語句以及相應的引數資訊。

  • Configuration        MyBatis所有的配置資訊都維持在Configuration物件之中。

五、版本

本系列採用的資料庫為MySQL,Mybatis版本為3.4.6。以下是pom檔案座標。

<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
		
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis-spring</artifactId>
	<version>1.3.2</version>
</dependency>

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>6.0.6</version>
</dependency>

<dependency>
	<groupId>com.mchange</groupId>
	<artifactId>c3p0</artifactId>
	<version>0.9.5.2</version>
</dependency>
複製程式碼

相關文章