zoukankan      html  css  js  c++  java
  • 深度 Mybatis 3 源码分析(一)SqlSessionFactoryBuilder源码分析

    MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的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对象。

    Reader reader = Resources.getResourceAsReader(resources);

    2. 使用SqlSessionFactoryBuilder获取SqlSessionFactory

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

    源码分析:

    2.1.进入到build 传递reader有参数构造函数

    最终执行

    2.2. SqlSessionFactoryBuilder使用XMLConfigBuilder解析配置文件,封装成Configuration对象。

     

    注意: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的执行逻辑

  • 相关阅读:
    websocket使用nginx作为反向代理
    curl模拟http发送get或post接口测试
    linux tail -f messages查看控制台失败
    shell中使用>/dev/null 2>&1 丢弃信息
    mysql备份与还原
    计算机中RAM和ROM
    *C语言有关指针的变量声明中的几个易错点
    五种存储变量补充~作用域和存储时期
    typedef和#define的简单比较
    fopen()函数参数
  • 原文地址:https://www.cnblogs.com/hlkawa/p/10981542.html
Copyright © 2011-2022 走看看