Mybatis的源碼分析

Mybatis執行流程

流程圖

在這裏插入圖片描述

mybaits 流程圖的上半部分更多的是完成初始化
下半部分主要是實現增刪改查操作

座標添加

通過添加maven座標 ,進而添加其jar包與源碼 ,方便快捷 ; 也可以找到自己的mybatis項目 ,查看相關源碼

<dependencies>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.2.8</version>
		</dependency>

源碼分析

1. Configuration.xml

該配置文件是MyBatis 的全局配置文件,在這個文件中可以配置諸多項目。常用的內容是別名設置,攔截器設置等。

<?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>
       <properties resource="db.properties">
    </properties>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/bjsxt/mapper/UserMapper.xml"/>
    </mappers>

  </configuration>

Properties(屬性)
將數據庫連接參數單獨配置在db.properties 中, 放在類路徑下。這樣只需要在SqlMapConfig.xml 中加載db.properties 的屬性值。這樣在SqlMapConfig.xml 中就不需要對數據庫連接參數硬編碼。
將數據庫連接參數只配置在db.properties 中,原因:方便對參數進行統一管理

Settings(全局配置參數)
Mybatis 全局配置參數,全局參數將會影響mybatis 的運行行爲。比如:開啓二級緩存、開啓延遲加載

TypeAliases(類型別名)
類型別名是爲Java 類型命名一個短的名字。它只和XML 配置有關, 只用來減少類完
全限定名的多餘部分

Plugins(插件)
MyBatis 允許你在某一點攔截已映射語句執行的調用。默認情況下,MyBatis 允許使用
插件來攔截方法調用

Environments(環境集合屬性對象)
MyBatis 可以配置多種環境。這會幫助你將SQL 映射應用於多種數據庫之中。但是要
記得一個很重要的問題:你可以配置多種環境,但每個數據庫對應一個SqlSessionFactory。
所以,如果你想連接兩個數據庫,你需要創建兩個SqlSessionFactory 實例,每個數據
庫對應一個。

Environment(環境子屬性對象)
ransactionManager(事務管理)
在MyBatis 中有兩種事務管理器類型(也就是type=”[JDBC|MANAGED]”)
DataSource(數據源)

Mappers(映射器)
指定映射配置文件位置

<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<package name="org.mybatis.builder"/>

2. Mapper.xml

Mapper.xml 映射文件中定義了操作數據庫的sql,每個sql 是一個statement,映射文件
是mybatis 的核心

<?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="com.bjsxt.mapper.UsersMapper">
	<select id="selectUsers" resultType="com.bjsxt.pojo.User">
		select * from users
	</select>
</mapper>

ResultMap
Mybatis 中可以使用resultMap 完成高級輸出結果映射。如果查詢出來的列名和定義的pojo 屬性名不一致,就可以通過定義一個resultMap 對列名和pojo 屬性名之間作一個映射關係

Cache
開啓二級緩存

Select
查詢語句

Insert
插入語句

Update
更新語句

Delete
刪除語句

3. Resources

Resources 工具類會從路徑中加載資源,並返回一個輸入流對象,對於資源文件的加載
提供了簡易的使用方法。

如何進入Resource

在這段代碼中 , 選中Resources , 通過鼠標 ctrl+鼠標左鍵進入 Resources類
InputStream inputStream = Resources.getResourceAsStream(resource);


import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import com.bjsxt.mapper.UsersMapper;
import com.bjsxt.pojo.User;

public class Test {

	public static void main(String[] args) throws Exception {
		    String resource = "SqlMapperClient.xml";
		    
		    //通過鼠標 ctrl+鼠標左鍵進入 Resources類
	        InputStream inputStream = Resources.getResourceAsStream(resource);
	        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	 
	        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.REUSE);
	        try {
	        	//sqlSession.selectOne("");
	            UsersMapper userMapper = sqlSession.getMapper(UsersMapper.class);
	            List<User> list = userMapper.selectUsers();
	            for (User user : list) {
	                System.out.printf(user.toString());
	            }
	        } finally {
	            sqlSession.close();
	        }
	}

}

方法解釋

加載一個資源有很多方式:
對於簡單的只讀文本數據,加載爲Reader。
對於簡單的只讀二進制或文本數據,加載爲Stream。
對於可讀寫的二進制或文本文件,加載爲File。
對於只讀的配置屬性文件,加載爲Properties。
對於只讀的通用資源,加載爲URL。

按以上的順序,Resources 類加載資源的方法如下(全都在本類,如下圖的類結構):
Reader getResourceAsReader(String resource);
Stream getResourceAsStream(String resource);
File getResourceAsFile(String resource);
Properties getResourceAsProperties(String resource);
Url getResourceAsUrl(String resource);

在這裏插入圖片描述

4. SqlSessionFactoryBuilder

該類是SqlSessionFactory(會話工廠)的構建者類,之前描述的操作其實全是從這裏面
開啓的,首先就是調用XMLConfigBuilder 類的構造器來創建一個XML 配置構建器對象,
利用這個構建器對象來調用其解析方法parse()來完成Configuration 對象的創建,之後以這
個配置對象爲參數調用會話工廠構建者類中的build(Configuration config) 方法來完成
SqlSessionFactory(會話工廠)對象的構建。

在這裏插入圖片描述

5. XMLConfigBuilder

該類是XML 配置構建者類,是用來通過XML 配置文件來構建Configuration 對象實例,
構建的過程就是解析Configuration.xml 配置文件的過程,期間會將從配置文件中獲取到的指
定標籤的值逐個添加到之前創建好的默認Configuration 對象實例中

在這裏插入圖片描述

6. Configuration

該對象是Mybatis 的上下文對象,實例化這個類的目的就是爲了使用其對象作爲項目全
局配置對象,這樣通過配置文件配置的信息可以保存在這個配置對象中,而這個配置對象在
創建好之後是保存在JVM 的Heap 內存中的,方便隨時讀取。不然每次需要配置信息的時
候都要臨時從磁盤配置文件中獲取,代碼複用性差的同時,也不利於開發 (上下文對象 ,保存配置信息)
在這裏插入圖片描述

7. DefaultSqlSessionFactory

SqlsessionFactory 該接口是會話工廠, 是用來生產會話的工廠接口,
DefaultSqlSessionFactory 是其實現類,是真正生產會話的工廠類,這個類的實例的生命週期
是全局的,它只會在首次調用時生成一個實例(單例模式)
,就一直存在直到服務器關閉。

在這裏插入圖片描述

8. Executor

執行器接口,SqlSession 會話是面向程序員的,而內部真正執行數據庫操作的卻是
Executor 執行器,可以將Executor 看作是面向MyBatis 執行環境的,SqlSession 就是門面貨,
Executor 纔是實幹家。通過SqlSession 產生的數據庫操作,全部是通過調用Executor 執行器
來完成的。
Executor 是跟SqlSession 綁定在一起的,每一個SqlSession 都擁有一個新的Executor 對
象,由Configuration 創建。

在這裏插入圖片描述

繼承結構

在這裏插入圖片描述
在這裏插入圖片描述

BaseExecutor

SimpleExecutor:
每執行一次update 或select,就開啓一個Statement 對象,用完立刻關閉Statement 對象。(可以是Statement 或PrepareStatement 對象)

在這裏插入圖片描述
ReuseExecutor:
執行update 或select,以sql 作爲key 查找Statement 對象,存在就使用,不存在就創建,用完後,不關閉Statement 對象,而是放置於Map<String, Statement>內,供
下一次使用。(可以是Statement 或PrepareStatement 對象)
在這裏插入圖片描述
BatchExecutor:
執行update(沒有select,JDBC 批處理不支持select),將所有sql 都添加到批處理中(addBatch()),等待統一執行(executeBatch()),它緩存了多個Statement對象,每個Statement 對象都是addBatch()完畢後,等待逐一執行

在這裏插入圖片描述

CachingExecutor

先從緩存中獲取查詢結果,存在就返回,不存在,再委託給Executor delegate 去數據庫取,delegate 可以是上面任一的SimpleExecutor、ReuseExecutor、BatchExecutor。RoutingStatementHandler,這是一個封裝類,它不提供具體的實現,只是根據Executor的類型,創建不同的類型StatementHandler。
在這裏插入圖片描述

9. StatementHandler

該類是Statement 處理器,封裝了Statement 的各種數據庫操作方法execute(),可見MyBatis 其實就是將操作數據庫的JDBC 操作封裝起來的一個框架,同時還實現了ORM 罷
了。

在這裏插入圖片描述

10. ResultSetHandler

結果集處理器,如果是查詢操作,必定會有返回結果,針對返回結果的操作,就要使用
ResultSetHandler 來進行處理,這個是由StatementHandler 來進行調用的。這個處理器的作用
就是對返回結果進行處理。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章