Spring-Mybatis源码解析--Mybatis配置文件解析

文章目录

  • 前言
  • 一、准备工作
    • 1.1 依赖准备:
    • 1.2 配置文件准备:
    • 1.3 代码准备:
  • 二、配置文件加载:
    • 2.1 SqlSessionFactoryBuilder().build(reader)
    • 2.2 parser.parse() :
  • 三、 执行sql :
  • 总结


前言

Spring 整合Mybatis 后,如何对其配置文件进行加载和解析,如何进行数据的CRUD。


一、准备工作

1.1 依赖准备:

<dependency>
   <groupId>com.baomidougroupId>
    <artifactId>mybatis-plus-boot-starterartifactId>
    <version>3.5.2version>
dependency>

<dependency>
    <groupId>com.mysqlgroupId>
    <artifactId>mysql-connector-jartifactId>
dependency>
<dependency>

1.2 配置文件准备:


DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="dbconfig.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>
        <environment id="development1">
            
            <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>
        <environment id="development2">
            
            <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="mapper/Test.xml"/>
    mappers>
configuration>

dbconfig.properties:

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3406/mybatis
jdbc.username=root
jdbc.password=ddsoft

1.3 代码准备:

TestMapper:

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.Map;

public interface TestMapper {
    @Select("select '123'")
    public String selectOne(String str);

    public Map selectById(@Param(value = "id")  String id);

}

TestMapper.xml


DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springdabaihua.mapper.TestMapper">


    <select id="selectById" resultType="java.util.Map">
        select * from tb_user
        where 1=1
        <if test="id != null and id != ''">
            and id =#{id}
        if>
    select>
mapper>

TestMain:

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;
import java.util.Map;

public class TestMain {
    public static void main(String[] args) throws IOException {
        String resource ="mybatis-config.xml";
        Reader reader = Resources.getResourceAsReader(resource);
        // 解析数据源 解析 xml 中的sql 语句
        SqlSessionFactory sqlSessionFactory =   new SqlSessionFactoryBuilder().build(reader);
        // 解析 Executor 执行器
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 执行sql
        Object abc = sqlSession.selectOne("com.example.springdabaihua.mapper.TestMapper.selectOne","123");
        System.out.println("abc = " + abc);

        Map abc1 =(Map) sqlSession.selectOne("com.example.springdabaihua.mapper.TestMapper.selectById","1");
        abc1.entrySet().stream().forEach(e->{
            System.out.println("e.toString() = " + e.toString());
        });
//        System.out.println("abc1 = " + abc1);
    }
}

二、配置文件加载:

2.1 SqlSessionFactoryBuilder().build(reader)

public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    SqlSessionFactory var5;
    try {
		// 配置文件加载读取 成为 Document 文件
        XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
		// 具体标签值解析并设置
        var5 = this.build(parser.parse());
    } catch (Exception var14) {
        throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
    } finally {
        ErrorContext.instance().reset();

        try {
            if (reader != null) {
                reader.close();
            }
        } catch (IOException var13) {
        }

    }

    return var5;
}

2.2 parser.parse() :

// 解析资源并返回 Configuration

public Configuration parse() {
    if (this.parsed) {
        throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    } else {
        this.parsed = true;
        // 解析configuration 标签
        this.parseConfiguration(this.parser.evalNode("/configuration"));
        return this.configuration;
    }
}

parseConfiguration:

private void parseConfiguration(XNode root) {
    try {
		// 解析获取 数据库连接等
        this.propertiesElement(root.evalNode("properties"));
		// 解析 全局配置
        Properties settings = this.settingsAsProperties(root.evalNode("settings"));
		// 读取虚拟文件,一般不用
        this.loadCustomVfs(settings);
		// 加载 日志的实现
        this.loadCustomLogImpl(settings);
		// 加载别名处理器 TypeAliasRegistry  我们在Mapper.xml 文件中可以 直接在 
//