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

相关文章
相关标签/搜索