Mybatis深刻源碼分析之SqlSessionFactoryBuilder源碼分析

本章知識點html

1.MyBatis環境搭建與MyBatis基礎內容回顧
2.MyBatis大致執行流程源碼分析
3.SqlSessionFactoryBuilder源碼分析
4.XMLConfigBuilder源碼分析
5.Configuration源碼分析java

一、爲何要使用Mybatismysql

MyBatis 是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可使用簡單的 XML 或註解來配置和映射原生類型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 對象)爲數據庫中的記錄。git

二、Mybatis環境快速入門github

maven依賴信息redis

<dependencies>
    <!-- mybatis核心包 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.3.0</version>
    </dependency>
    <!-- mysql驅動包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.29</version>
    </dependency>
    <!-- junit測試包 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
</dependencies>

建立Mybatis配置文件configurationspring

<?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="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!-- 數據庫鏈接相關配置 ,這裏動態獲取config.properties文件中的內容-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!-- mapping文件路徑配置 -->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>

</configuration>

mapper配置文件sql

<?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,namespace的值習慣上設置成包名+sql映射文件名,這樣就可以保證namespace的值是惟一的
例如namespace="com.mayikt.mapper.UserMapper"就是com.mayikt.mapper(包名)+userMapper(userMapper.xml文件去除後綴)
 -->
<mapper namespace="com.mayikt.mapper.UserMapper">
    <!-- 在select標籤中編寫查詢的SQL語句, 設置select標籤的id屬性爲getUser,id屬性值必須是惟一的,不可以重複
    使用parameterType屬性指明查詢時使用的參數類型,resultType屬性指明查詢返回的結果集類型
    resultType="com.mayikt.entity.User"就表示將查詢結果封裝成一個User類的對象返回
    User類就是users表所對應的實體類
    -->
    <!--
        根據id查詢獲得一個user對象
     -->
    <select id="getUser" parameterType="int"
            resultType="com.mayikt.entity.UserEntity">
        select * from user where id=#{id}
    </select>
</mapper>

運行Mybatis代碼數據庫

try {
    // 1.mybatis配置文件
    String resources = "mybatis.xml";
    // 2.獲取Reader對象
    Reader resourceAsReader = Resources.getResourceAsReader(resources);
    // 3.獲取SqlSessionFactoryBuilder
    SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsReader);
    // 4.建立對應的session
    SqlSession sqlSession = build.openSession();
    // 5.獲取對應的mapper
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    // 6.執行方法
    UserEntity user = userMapper.getUser(1);
    System.out.println("name:" + user.getName());
} catch (Exception e) {
    e.printStackTrace();
}

數據表結構緩存

CREATE TABLE `user` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Mybatis核心配置文件

properties(屬性)

Java屬性文件能夠配置直觀的,如:

<properties>
        <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
        <property name="jdbc.url" value="jdbc:mysql:///mybatis"/>
        <property name="jdbc.username" value="root"/>
        <property name="jdbc.password" value="root"/>
</properties>

或者經過直接引入屬性文件,如:

<properties resource="db.properties"></properties>

而後db.properties文件中須要配置:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis
jdbc.username=root
jdbc.password=root

typeAliases(類型別名)

類型別名是Java類型的簡稱

逐個設置,如:

<typeAliases>
        <typeAlias type="com.mayikt.entity.User" alias="user"/>
</typeAliases>

MyBatis 的配置文件包含了會深深影響 MyBatis 行爲的設置和屬性信息。 配置文檔的頂層結構以下:

參考Mybatis官方中文文檔

http://www.mybatis.org/mybatis-3/zh/index.html

MyBatis官方GitHub地址

MyBatis官方GitHub地址爲https://github.com/mybatis 。在官方GitHub 中能夠看到MyBatis的多個子項目。例如:

mybatis-3 ( https://github.com/mybatis/mybatis-3 ): MyBatis 源碼
generator ( https://github.com/mybatis/generator ):代碼生成器,能夠生成一些常見的基本
方法,提升工做效率。
ehcache-cache( https://github.com/mybatis/ehcache-cache ):默認集成Ehcache 的緩存實現。
redis-cache ( https://github.com/mybatis/redis-cache ) : 默認集成Redis 的緩存實現。
spring (https://github.com/mybatis/spring ):方便和Spring 集成的工具類。
mybatis-spring-boot ( https://github.com/mybatis/mybatis-spring-boot ):方便和Spring Boot集成的工具類。

核心源碼分析時序圖

Mybatis大致架構流程分析

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

reader=Resource.getResourceAsReader(resource);

2.使用SqlSessionFactoryBuilder獲取SqlSessionFactory源碼分析

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

源碼分析到:

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

最終執行

XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties)最終建立了一個Configuration對象

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

注意XMLConfigBuilder運行以後,只能被解析一次,不然會拋出異常。

2.將配置文件中的mappers註冊到configuration的mapperRegister中

private void mapperElement(XNode parent) throws Exception {
    if (parent != null) {
      for (XNode child : parent.getChildren()) {
        if ("package".equals(child.getName())) {
          String mapperPackage = child.getStringAttribute("name");
          configuration.addMappers(mapperPackage);
        } else {
          String resource = child.getStringAttribute("resource");
          String url = child.getStringAttribute("url");
          String mapperClass = child.getStringAttribute("class");
          if (resource != null && url == null && mapperClass == null) {
            ErrorContext.instance().resource(resource);
            InputStream inputStream = Resources.getResourceAsStream(resource);
            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
            mapperParser.parse();
          } else if (resource == null && url != null && mapperClass == null) {
            ErrorContext.instance().resource(url);
            InputStream inputStream = Resources.getUrlAsStream(url);
            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
            mapperParser.parse();
          } else if (resource == null && url == null && mapperClass != null) {
            Class<?> mapperInterface = Resources.classForName(mapperClass);
            configuration.addMapper(mapperInterface);
          } else {
            throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
          }
        }
      }
    }
  }

真正執行方法

因此configuration中的mapperRegistry註冊mapperInterface接口。

3.使用configuration獲取默認的DefaultSqlSessionFactory

總結:

一、獲取本地InputStreamReader對象(Mybatis配置文件)

二、調用SqlSessionFactoryBuilder

####2.一、使用XMLConfigBuilder解析Mybatis配置文件,裝配到Configuration中

####2.二、再將配置文件中的Mapper添加到Configuration的mapperRegistry實現註冊

########備註:mapperRegistry存放當前全部的mapper文件

####2.三、使用Configuration獲取默認的DefaultSqlSessionFactory

版權@須臾之餘https://my.oschina.net/u/3995125

本文參考:螞蟻課堂:http://www.mayikt.com

本文參考:螞蟻課堂:http://www.mayikt.com

本文參考:螞蟻課堂:http://www.mayikt.com

相關文章
相關標籤/搜索