深度 Mybatis 3 源碼分析(一)SqlSessionFactoryBuilder源碼分析

MyBatis消除了幾乎全部的JDBC代碼和參數的手工設置以及對結果集的檢索封裝。MyBatis能夠使用簡單的XML或註解用於配置和原始映射,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數據庫中的記錄。java

Mybatis環境快速入門

Maven依賴信息

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>sourceanalysis</artifactId>
        <groupId>com.brian</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>


    <artifactId>mybatis3</artifactId>
    <groupId>com.brian</groupId>
    <version>0.0.1-SNAPSHOT</version>
    <description>源碼分析 - mybatis3源碼分析</description>


    <dependencies>
        <!--mysql數據庫驅動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>

        <!-- mybatis ORM框架 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
    </dependencies>

</project>

建立mybatis配置文件 mybatis.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>
    <!-- 環境配置 -->
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <!-- 數據庫鏈接相關配置 ,這裏動態獲取config.properties文件中的內容-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:14110/brian?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- mapping文件路徑配置 -->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>

</configuration>

Mapper配置文件

<?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="mapper.UserMapper">
    <select id="getUser" parameterType="int"
            resultType="entity.User">
        select * from user where id=#{id}
    </select>
</mapper>

運行MyBatis代碼

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

import java.io.IOException;
import java.io.Reader;

/**
 * @program: architect
 * @author: Brian Huang
 * @create: 2019-06-04 22
 **/
public class MybatisApp {

    public static void main(String[] args) {
        try {
            //1.定義配置文件
            String resource = "mybatis.xml";
            //2.獲取InputStreamReader IO流
            Reader reader = Resources.getResourceAsReader(resource);
            //3.獲取SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //4.獲取Session
            SqlSession session = sqlSessionFactory.openSession();
            //5.執行mapper接口方法
            UserMapper mapper = session.getMapper(UserMapper.class);
            System.out.println("--result--: " + mapper.getUser(1).toString());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

數據表結構

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶名',
  `password` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密碼,加密存儲',
  `phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '註冊手機號',
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '註冊郵箱',
  `created` datetime(0) NOT NULL,
  `updated` datetime(0) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE,
  UNIQUE INDEX `phone`(`phone`) USING BTREE,
  UNIQUE INDEX `email`(`email`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 36 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用戶表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

Mybatis大致架構流程分析

1. 讀取resources獲取對應的Reader對象。mysql

Reader reader = Resources.getResourceAsReader(resources);sql

2. 使用SqlSessionFactoryBuilder獲取SqlSessionFactory數據庫

SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);apache

源碼分析:session

2.1.進入到build 傳遞reader有參數構造函數mybatis

最終執行架構

2.2. SqlSessionFactoryBuilder使用XMLConfigBuilder解析配置文件,封裝成Configuration對象。app

 

注意:parsed = false,避免maybatis.xml被加載屢次,由於咱們的configuration是全局的因此只能被解析一次框架

 2.3 執行environmentsElement()  方法

 

此處for循環是environment可能回配置多個運行環境如dev,test,prod等

 2.4 執行mapperElement()方法 解析mybatis.xml裏面的<mappers>節點

 

這裏的Mapper有兩種掃描的方式 package和resource,根據我上面的mybatis.xml配置文件,這裏會走第一個判斷

2.5 執行XMLMapperBuilder的parse()方法,解析UserMapper.xml

2.5.1 isResourceLoaded() 判斷避免mapper被重複解析

 

2.5.2 configurationElement()執行具體的解析UserMapper.xml邏輯

2.5.3 addLoadedResource()方法Mapper路徑放入到loadedResoures中

 

 2.5.4 執行bingMapperForNamesapce() 將UserMapper.XML和UserMapper.java 進行映射

 

總環下流程圖 (PS 圖畫的不是太好看) 紅色框爲SqlSessionFactoryBuilder的執行邏輯

相關文章
相關標籤/搜索