手写 Mybatis框架及分析 Version 2.0 版本

​ 上篇文章我们介绍了将JDBC源码改造成简单的Mybatis V1版本,这个V1版本的目的是打开我们手写Mybatis源码的思路。接下来,这篇文章中我们要来分析并手写Mybatis V2版本的源码了。将Mybatis V1版本升级成 Mybatis V2 版本1、将 properties配置文件升级成 xml文件2、按照 Mybatis的用法,将 xml配置文件分成 全局配置文件和映射文件3、对 xml配置文件进行解析解析Mybatis的全局配置文件和映射文件1、全局配置文件​ 全局配置文
摘要由CSDN通过智能技术生成

​ 上篇文章我们介绍了将JDBC源码改造成简单的Mybatis V1版本,这个V1版本的目的是打开我们手写Mybatis源码的思路。接下来,这篇文章中我们要来分析并手写Mybatis V2版本的源码了。

将Mybatis V1版本升级成 Mybatis V2 版本

1、将 properties配置文件升级成 xml文件

2、按照 Mybatis的用法,将 xml配置文件分成 全局配置文件和映射文件

3、对 xml配置文件进行解析

解析Mybatis的全局配置文件和映射文件

1、全局配置文件

​ 全局配置文件包含了Mybatis所有的配置信息,包括全局配置文件信息和映射文件信息,我们来看一下我们的全局配置文件都有哪些东西(这里的配置文件指的是我们按照Mybatis的架构自己写的简单版的配置文件,映射文件也一样)。
在这里插入图片描述
​ 从图中我们可以看出,Mybatis全局配置文件有一个根标签,这个标签在被解析后会被封装到一个Configuration对象中,这个Configuration对象就包含了Mybatis的全部配置信息,包括全局配置信息和映射信息。

2、映射文件

​ 映射文件中包含的是sql语句相关的信息,这里可以将映射文件分成几个大块,我们用不同颜色的方框给标示出来,下面我们对每个部位进行一一讲解:

在这里插入图片描述

1、黑色框 表示的是整个mapper映射文件,根标签是mapper,他有一个很重要的属性 namespace,它是 statementId的重要组成部分。

2、红色框 表示的是 、、、 标签,他们表示的是 SQL的 CRUD相关的信息,每个 CRUD标签都是一个 MappedStatement对象。

​ 以标签为例,它封装了 SQL语句,入参类型,映射结果类型,还有statement的类型。也就是标签的内容和属性。

3、橙色框 表示的是 sqlSource,其中封装的SQL源信息,并且还可以对 #{} 和 ${} 进行解析,每个 statement对应一个 sqlSource,而每个sqlSource对应一颗 sqlNode树。

4、紫色框 表示 sqlNode,它封装了SQL的节点信息。sqlNode之间可以平行,也可以相互嵌套,这样多个sqlNode节点,就组成了一颗sqlNode树,也就是组成了一个sqlSource。

5、注意:namespace和statement标签的id属性共同组成了statementId,这是MappedStatement的唯一标识。

开始手写 Mybatis-V2版本源码

1、创建Configuration类

根据前面对全局配置文件的分析,我们可以来创建Configuration类了,Configuration类中两个重要的属性:

  • 封装了数据库信息的 DataSource数据源,
  • 封装了 映射文件的 Map集合
package com.mybatis.v2.config;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author :白银杰
 * @version :
 * @date :Created in 2020/12/7 14:43
 * @description :封装了 Mybatis中 xml文件的所有配置信息
 * @modified by  :
 */
public class Configuration {
   
    /**
     * 封装了数据源相关的信息
     */
    private DataSource dataSource;

    /**
     * 封装了所有statement标签的信息
     * key 是 namespace + statement标签的id属性组成的 statementId
     * value 是 MappedStatement对象
     */
    private Map<String, MappedStatement> mappedStatements = new HashMap<String, MappedStatement>();

    public DataSource getDataSource() {
   
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
   
        this.dataSource = dataSource;
    }

    /**
     * 通过 MappedStatementId获取 MappedStatement对象
     *
     * @param mappedStatementId
     * @return
     */
    public MappedStatement getMappedStatementById(String mappedStatementId) {
   
        return mappedStatements.get(mappedStatementId);
    }

    /**
     * 向map集合中添加 statementId 和 statement对象
     *
     * @param mappedStatementId namespace + statement的id属性 = statementId
     * @param mappedStatement   statement
     */
    public void setMappedStatement(String mappedStatementId, MappedStatement mappedStatement) {
   
        this.mappedStatements.put(mappedStatementId, mappedStatement);
    }
}

在这里,我们用到了 MappedStatement这个类,这个类标示的就是我们映射文件中是 statement标签(CRUD标签),这里封装了Mybatis映射文件中 statement标签的全部信息。

package com.mybatis.v2.config;

import com.mybatis.v2.sqlsource.SqlSource;

/**
 * @author :白银杰
 * @version :
 * @date :Created in 2020/12/7 15:03
 * @description :
 * @modified by  :
 */
public class MappedStatement {
   
    private String statementId;
    private String resultType;
    private Class resultTypeClass;
    private String statementType;
    private SqlSource sqlSource;

    /**
     * @param statementId     MappedStatement的唯一标识,由 namespace + StatementId 组成
     * @param resultType      返回结果类型
     * @param resultTypeClass
     * @param statementType   statement类型,包括 statement、PreparedStatement、CallableStatement等
     * @param sqlSource       sql源信息,包括对#{} 和 ${} 的解析,是个接口
     */
    public MappedStatement(String statementId, String resultType,
                           Class resultTypeClass, String statementType, SqlSource sqlSource) {
   
        this.statementId = statementId;
        this.resultType = resultType;
        this.resultTypeClass = resultTypeClass;
        this.statementType = statementType;
        this.sqlSource = sqlSource;
    }

    public String getStatementId() {
   
        return statementId;
    }

    public void setStatementId(String statementId) {
   
        this.statementId = statementId;
    }

    public String getResultType() {
   
        return resultType;
    }

    public void setResultType(String resultType) {
   
        this.resultType = resultType;
    }

    public Class getResultTypeClass() {
   
        return resultTypeClass;
    }

    public void setResultTypeClass(Class resultTypeClass) {
   
        this.resultTypeClass = resultTypeClass;
    }

    public String getStatementType() {
   
        return statementType;
    }

    public void setStatementType(String statementType) {
   
        this.statementType = statementType;
    }

    public SqlSource getSqlSource() {
   
        return sqlSource;
    }

    public void setSqlSource(SqlSource sqlSource) {
   
        this.sqlSource = sqlSource;
    }
}

而在MappedStatement类中,我们又用到了sqlSource接口,那么我们再去创建一个sqlSource接口:

package com.mybatis.v2.sqlsource;

/**
 * @author :白银杰
 * @date :Created in 2020/12/7 15:26
 * @description: 这是一个接口,每个statement都表示一个SQLSource,
 * 每个SQLSource都表示一颗sqlNode树,
 * 每颗sqlNode树都由多个sqlNode节点组成
 * @modified by:
 * @version:
 */
public 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值