Mybatis最硬核的API是什么

发布时间:2021-10-20 15:40:30 作者:iii
来源:亿速云 阅读:163

本篇内容主要讲解“Mybatis最硬核的API是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Mybatis最硬核的API是什么”吧!

1、Mybatis 架构与核心API

不出意外的话,在后续源码剖析相关文章中,我们会对 Mybatis 的源码进行一次大扫荡,一起挖掘每一处值得大家深入理解/记忆的知识点。而在本文中,我们主要先把 Mybatis 的架构/层次铺开,俯视 Mybatis 架构的设计全貌,再把几个硬核的 API 详细消化。

整体顺序脉络,希望让你有所期待 ~

Mybatis最硬核的API是什么

我们先简单揭开 Mybatis 神秘的源码包,

瞅瞅 Ta 大致目录结构 :

Mybatis最硬核的API是什么

看,Mybatis 的源代码包整齐划一排在 org.apache.ibatis 目录下,基本设计用途我简单梳理成上面这张图,方便大家直观理解,当然只看源码包目录结构,难免会显得枯燥无物,所以我们再看一下,其实 Mybatis 的源码包功能上可以是这么划分:

Mybatis最硬核的API是什么

上图让我们对 Mybatis 的架构有了抽象的理解。

然而,实际上具体的职能分工,核心 API 的场景应用,到底会是怎样一套流程呈现呢?

看下面这幅功能架构设计,或许你能更好的理解。

Mybatis最硬核的API是什么

根据 Mybatis 功能架构我们划分成三层

我们知道,Mybatis 框架让用户只需要提供配置信息,并且专注于 SQL 的编写即可,对于连接管理数据库/事务,或实际的 SQL 参数映射/语句执行/结果集映射等操作,作为用户都并不需要操心和参与。

但是,好奇的我们其实想知道,Mybatis 核心部分的数据处理在整体流程中,是如何支撑用户请求?同时各个构件之间交互,又是怎样流转呢?

很巧,我这里有一张图,介绍了整体流程:

Mybatis最硬核的API是什么

根据以上框架流程图进行讲解

针对以上总体框架流程涉及到的这些硬核 API,下面我们逐个展开介绍,但不会详细剖析源码与原理,包括构建细节,因为这些我们在后续的源码剖析章节中都会详细分析。

Mybatis最硬核的API是什么

2、Configuration – 全局配置对象

对于 Mybatis 的全局配置对象 Configuration,我相信无论是初学者还是资深玩家,都不会陌生。整个 Mybatis 的宇宙,都围绕着 Configuration 转。Configuration 对象的结构和 config.xml 配置文件的内容几乎相同,涵盖了properties (属性),settings (设置),typeAliases (类型别名),typeHandlers (类型处理器),objectFactory (对象工厂),mappers (映射器)等等,之前我们有专门的一篇文章详细进行介绍,感兴趣的朋友往上翻到目录列表,找到 《Mybatis系列全解(四):全网最全!Mybatis配置文件XML全貌详解》 一文详细品味一番吧。

Mybatis最硬核的API是什么

配置对象 Configuration 通过解析器 XMLConfigBuilder 进行解析,把全局配置文件 Config.xml 与 映射器配置文件 Mapper.xml 中的配置信息全部构建成完整的 Configuration 对象,后续我们源码分析时详细剖析整个过程。

Mybatis最硬核的API是什么

3、Resources – 资源辅助类

我们知道,像 Configuration 和 Mapper 的配置信息存放在 XML 文件中,Mybatis 框架在构建配置对象时,必须先把 XML 文件信息加载成流,再做后续的解析封装,而 Resources 作为资源的辅助类,恰恰干的就是这个活,无论是通过加载本地资源或是加载远程资源,最终都会通过 类加载器 访问资源文件并输出文件流。

Mybatis最硬核的API是什么

//加载核心配置文件
InputStream resourceAsStream = 
    Resources.getResourceAsStream("Config.xml");

Resources 实实在在提供了一系列方法分分钟解决你的文件读取加载问题:

Mybatis最硬核的API是什么

Mybatis最硬核的API是什么

4、SqlSessionFactoryBuilder – 会话工厂构建器

我们一撞见 xxxBuilder ,就大致能知道它是某类对象的构建器,这里 SqlSessionFactoryBuilder 也是一样,它是 Mybatis 中的一个会话工厂构建器,在资源辅助类 Resources 读取到文件流信息之后,它负责解析文件流信息并构建会话工厂 SqlSessionFactory。(解析的配置文件包含:全局配置 Configuration 与映射器 Mapper)

Mybatis最硬核的API是什么

在程序应用端,我们一般使用 SqlSessionFactoryBuilder 直接构建会话工厂:

// 获得sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = 
    new SqlSessionFactoryBuilder().build(resourceAsStream);

当然,如果你集成了 Spring 框架的项目,则不需要自己手工去构建会话工厂,直接在 Spring 配置文件中指定即可,例如指定一个 bean 对象,id 是 sqlSessionFactory,而 class 类指定为 org.mybatis.spring.SqlSessionFactoryBean 。

SqlSessionFactoryBuilder 内部通过解析器 XMLConfigBuilder 解析了文件流,同时封装成为配置对象 Configuration ,再把 Configuration 对象进行传递并构建实例。

public SqlSessionFactory build(
    InputStream inputStream, 
    String environment, 
    Properties properties) {
   
     
      // 配置解析器解析
      XMLConfigBuilder parser = 
          new XMLConfigBuilder(
          	inputStream,environment, properties);
    
      // 最终实例会话工厂
      return build(parser.parse()); 
    
}

最终实例会话工厂,其实 Mybatis 默认实现是 new 了一个DefaultSqlSessionFactory 实例。

// 最终实例会话工厂
public SqlSessionFactory build(Configuration config) {
   
    return new DefaultSqlSessionFactory(config);
}

会话工厂构建器 SqlSessionFactoryBuilder 应用了构建者模式,主要目的就是为了构建 SqlSessionFactory 对象,以便后续生产 SqlSession 对象,这个构造器基本上算是 Mybatis 框架的入口构建器,它提供了一系列多态方法 build(),支持用户使用 XML 配置文件或 Java API (Properties)来构建会话工厂 SqlSessionFactory 实例。

SqlSessionFactoryBuilder 的一生只为成就 SqlSessionFactory,当 SqlSessionFactory 一经实例,SqlSessionFactoryBuilder 使命完成,便可消亡,便可被丢弃。

Mybatis最硬核的API是什么

因此 SqlSessionFactoryBuilder 实例的最佳作用域是 方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。

SqlSessionFactoryBuilder 中灵活构建会话工厂的一系列接口:

Mybatis最硬核的API是什么

Mybatis最硬核的API是什么

5、SqlSessionFactory – 会话工厂

会话工厂 SqlSessionFactory 是一个接口,作用是生产数据库会话对象 SqlSession ,有两个实现类:

在介绍会话工厂构建器 SqlSessionFactoryBuilder 的时候,我们了解到构建器默认创建了 DefaultSqlSessionFactory 实例,并且会话工厂本身会绑定一个重要的属性 Configuration 对象,在生产会话时,最终也会把 Configuration 配置对象传递并设置到会话 SqlSession 上。

Mybatis最硬核的API是什么

会话工厂可以简单创建 SqlSession 实例:

// 创建 SqlSession 实例
SqlSession session = sqlSessionFactory.openSession();

会话工厂创建 SqlSession 时,会绑定数据源、事务处理、执行器等等,默认会话工厂实现类 DefaultSqlSessionFactory 在创建会话对象时,最终都会调用 openSessionFromDataSource 方法 ,即是如此实现:

// 每一个 openSession 最终都会调用此处
private SqlSession openSessionFromDataSource(
    ExecutorType execType, 
    TransactionIsolationLevel level, 
    boolean autoCommit) {
   
    
    // 环境配置
    final Environment environment = 
        configuration.getEnvironment();
    
    // 事务工厂
    final TransactionFactory transactionFactory = 
        getTransactionFactoryFromEnvironment(environment);
    
    // 事务
    Transaction tx =
        transactionFactory.newTransaction(
        environment.getDataSource(), 
        level, 
        autoCommit);
    
    // 执行器
    final Executor executor = 
        configuration.newExecutor(tx, execType);
    
    // 最终生成会话
    return new DefaultSqlSession(
          configuration, executor, autoCommit);
    
  }

另外,会话工厂其实提供了一系列接口来灵活生产会话 SqlSession,你可以指定:

Mybatis最硬核的API是什么

SqlSessionFactory 一旦被创建就应该在 应用的运行期间 一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是 应用作用域。 最简单的就是使用单例模式或者静态单例模式。

请记住,创建 SqlSessionFactory ,一次就好!

每个数据库对应一个 SqlSessionFactory 实例。SqlSessionFactory 一旦被创建, 它的生命周期应该与应用的生命周期相同 。所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个;而如果是三个数据库,就需要三个实例,依此类推。

Mybatis最硬核的API是什么

Mybatis最硬核的API是什么

6、SqlSession – 会话

SqlSession 是一个接口,有两个实现类:

简单来说,通过会话工厂构建出 SqlSession 实例之后,我们就可以进行增删改查了,默认实例 DefaultSqlSession 提供了如此多的方法供用户使用,有超过30个:

Mybatis最硬核的API是什么

sqlSession 的方法除了 CURD,还提供了事务的控制例如提交/关闭/回滚等、提供了配置对象的获取例如 getConfiguration()、提供了批量语句的执行更新例如 flushStatements()、提供了缓存清除例如 clearCache() 、提供了映射器的使用 getMapper() 等等。

Mybatis最硬核的API是什么

对于客户端应用层面来说,熟悉 sqlSession 的 API 基本就可以任意操作数据库了,不过我们希望想进一步了解 sqlSession 内部是如何执行 sql 呢?其实 sqlSession 是 Mybatis 中用于和数据库交互的 顶层类,通常将它与本地线程 ThreadLocal 绑定,一个会话使用一个 SqlSession,并且在使用完毕之后进行 关闭

之所以称 SqlSession 为数据交互的 顶层类,是它其实没有完成实质的数据库操作。根据之前的架构设计流程我们已经清晰的知道,SqlSession 对数据库的操作都会转发给具体的执行器 Executor 来完成 ;当然执行器也是甩手掌柜,执行器 Executor 会再分派给语句处理器 StatementHandler ,语句处理器会结合参数处理器 ParameterHandler ,共同完成最终的数据库执行处理操作(底层还是封装了 JDBC Statement 操作)。并在每个语句处理器 StatementHandler 处理完成数据库操作之后, 通过结果结处理器 ResultSetHandler 以及类型处理器 TypeHandler ,对底层 JDBC 返回的结果集进行映射封装,最终才返回预期的封装对象。

关注以下图示 sqlSession 红色高亮位置,详细描述了会话的实际执行路径:

Mybatis最硬核的API是什么

SqlSession 可以理解为一次数据库会话,一次会话当中既可以执行一次 sql ,也允许你批量执行多次,但是一旦会话关闭之后想要再执行 sql,那就必须重新创建会话。

Mybatis最硬核的API是什么

每个线程都应该有它自己的 SqlSession 实例,SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是 请求(request)或方法(method) 作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。

Spring 集成 Mybatis 之后,通过依赖注入可以创建线程安全的、基于事务的 SqlSession ,并管理他们的生命周期,推荐搭配使用。

Mybatis最硬核的API是什么

7、Executor – 执行器

Executor 是一个执行器接口,是 Mybatis 的调度核心,它定义了一组管理 Statement 对象与获取事务的方法,并负责 SQL 语句的生成和一级/二级查询缓存的维护等,SqlSessionFactory 在创建 SqlSession 时会同时创建执行器,并指定执行器类型,默认使用 SimpleExecutor 。执行器接口有5个子孙实现类,其中 BaseExecutor 是抽象类,另外4个子孙实现类分别是:SimpleExecutor 、BatchExecutor、ReuseExecutor、CachingExecutor。

Mybatis最硬核的API是什么

Mybatis 在构建 Configuration 配置类时默认把 ExecutorType.SIMPLE 作为执行器类型,当我们的会话工厂 DefaultSqlSessionFactory 开始生产 SqlSession 会话时,会同时构建执行器,此时就会依据配置类 Configuration 构建时指定的执行器类型来实例具体执行器 ,流程如下:

// 1、Configuration配置类构建时
// 指定了默认执行器类型为:普通执行器
protected ExecutorType defaultExecutorType 
    = ExecutorType.SIMPLE;

// 2、Configuration配置类中
// 提供方法获取默认执行器类型
public ExecutorType getDefaultExecutorType() {
   
    return defaultExecutorType;
}

// 3、会话工厂创建 SqlSession 实例时
SqlSession session = sqlSessionFactory.openSession();

// 4、openSession 实际逻辑
public SqlSession openSession() {
   
    return 
       openSessionFromDataSource(
           // 这里可就获取了默认执行器
           configuration.getDefaultExecutorType(), 
           null, 
           false
        );
}

这里,肯定有人想知道,我们能否指定其它执行器呢?

答案是:当然可以,有两种方式指定:

// 创建 SqlSession 实例
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.REUSE)
    
// ExecutorType是一个枚举
// 有三个值SIMPLE, REUSE, BATCH
<settings>
    <!--取值范围 SIMPLE, REUSE, BATCH -->
	<setting name="defaultExecutorType" value="REUSE"/>
</settings>

对于第二种 settings 的配置方式,其实之前我们在介绍 Mybatis 的配置文件中已经讲过,这里再简单说明一下,像上面配置 settings 中的属性 defaultExecutorType ,基本这些属性都是 Mybatis 额外提供给我们灵活设置的,就算我们不设置 Mybatis 也会有默认值,例如像 defaultExecutorType 的默认值就是 SIMPLE。你看一下 Mybatis 在解析 Configuration 配置时的默认构建,就会明白:

解析 Configuration 的解析器(类与具体方法的代码路径):

org.apache.ibatis.builder.xml.XMLConfigBuilder#settingsElement

我们截取部分代码逻辑,下面是设置默认执行器类型属性 defaultExecutorType 的内容:

// 配置文件解析器 
public class XMLConfigBuilder {
   
    
    // 最终解析到的 Configuration 对象
    protected final Configuration configuration;
    
    // 为 Configuration 对象设置属性
    private void settingsElement(Properties props) {
   
        
        // 设置默认执行器类型,默认是 SIMPLE
        configuration.setDefaultExecutorType(
            ExecutorType.valueOf(
                props.getProperty(
                    "defaultExecutorType", "SIMPLE")));
        
        // .... 当然这里还有很多属性设置
        // .... 只要你在<settings>中配置即可
    
    }
}

注意,到此我们知道可以根据业务需要指定执行器类型,例如 SIMPLE(普通执行器), REUSE(复用执行器), BATCH(批处理执行器)。

但是,有朋友就好奇了,那缓存执行器 CachingExecutor 好像不见说明呢?

确实如此,因为缓存执行器个其它三个执行器还不太一样,CachingExecutor 是需要我们开启二级缓存才会有,这里大家先不要思考什么是一级缓存,什么二级缓存,后续我们有一文会详细讲缓存整个知识内容。

大家先了解一个概念即可,就是 Mybatis 的一级缓存是默认开启的,不管你要不要,都会有一级缓存,而二级缓存呢,是默认关闭的,但允许我们手工开启。

对比开启二级缓存前后,执行器执行的区别吧!

Mybatis最硬核的API是什么

Mybatis最硬核的API是什么

其实我们实际操作数据库,不会直接接触到执行器 Executor ,不过我们确实可以了解一下基本的执行原理,下面列出了执行器接口提供的众多重载方法,基本用于事务/缓存/数据库管理与访问,可以知道一下:

Mybatis最硬核的API是什么

到此,对于执行器有了基本的认识,但是实际上,我们知道执行器自身没有去具体执行 SQL 语句,而是分派到语句处理器 StatementHandler ,语句处理器会结合参数处理器 ParameterHandler ,最终进行数据库操作。

Mybatis最硬核的API是什么

8、StatementHandler – 语句处理器

StatementHandler 是一个语句处理器接口,它封装了 JDBC Statement 操作,负责对 JDBC Statement 的操作,如 设置参数、结果集映射,是实际跟数据库做交互的一道。StatementHandler 语句处理器实例,是在执行器具体执行 CRUD 操作时构建的,默认使用 PrepareStatementHandler。语句处理器接口有5个子孙实现类,其中 BaseStatementHandler 是抽象类,另外4个子孙实现类分别是:SimpleStatementHandler、PrepareStatementHandler、CallableStatementHandler、RoutingStatementHandler。

Mybatis最硬核的API是什么

其实普通语句处理器、预执行语句处理器以及存储过程处理器,只是 Mybatis 对于 JDBC 的语句执行对象的简单包装而已,没有特别神秘,看以下 JDBC 的语句执行对象的类图关系也就能够清楚。

// 1、执行器构建语句处理器实例
public StatementHandler newStatementHandler(...) {
   
    
    // 构建路由语句处理器即可!
    StatementHandler statementHandler = 
        new RoutingStatementHandler(...);
    
    // 其它逻辑忽略...
    return statementHandler;
}

// 2、实际构造方法(路由关系)
public RoutingStatementHandler(...) {
   

    // 根据指定类型构造委托实例
    switch (ms.getStatementType()) {
   
      case STATEMENT:
        delegate = new SimpleStatementHandler(...);
        break;
      case PREPARED:
        delegate = new PreparedStatementHandler(...);
        break;
      case CALLABLE:
        delegate = new CallableStatementHandler(...);
        break;
      default:
        throw new ExecutorException(
            "Unknown statement type: " 
                + ms.getStatementType());
    }
}

我们前面介绍了执行器具体执行 CRUD 操作时,构造的语句处理器默认使用 PrepareStatementHandler ,不过有些好奇的脑袋就想问问,那我们能不能指定语句处理器类型呢?

当然可以,例如我们指定更新用户语句适用预编译处理语句处理器:

<!--取值范围 STATEMENT, PREPARED, CALLABLE -->
<update id="updateUser" statementType="STATEMENT">
    update t_user set name = #{newName}
</update>

当 Mybatis 在解析映射器中的每条语句时,会设置语句处理器类型:

// 语句对象解析器 
public class XMLStatementBuilder {
   
    
    // 解析语句节点
    public void parseStatementNode() {
    
        
        // 设置语句处理器类型
        // 默认是 PREPARED 类型
        StatementType statementType = 
         StatementType.valueOf(
            context.getStringAttribute(
                "statementType", 
                StatementType.PREPARED.toString()
            )
        ); 
    }  
}

所以,语句执行器与数据库的交互过程:

Mybatis最硬核的API是什么

当然,语句处理器接口 StatementHandler 提供了基本接口,一般我们没必要自定义实现类,所以可以简单看一下即可:

Mybatis最硬核的API是什么

Mybatis最硬核的API是什么

9、ParamerHandler – 参数处理器

ParameterHandler 是一个参数处理器接口,它负责把用户传递的参数转换成 JDBC Statement 所需要的参数,底层做数据转换的工作会交给类型转换器 TypeHandler,后面会介绍。

很显然,需要对传入的参数进行转换处理的 StatementHandler 实例只有两个,分别是:

上面在介绍语句处理器的时候,我们有介绍说基础语句处理器 BaseStatementHandler 在进行实例构建时,会同时构建参数处理器与结果集处理器,所以参数处理器就是在此时被构建。

// 基础语句处理器
public abstract class BaseStatementHandler{
   
    
    // 构造实例时
    protected BaseStatementHandler(...){
   
        
        // 其它逻辑可忽略...
        
        // 1、构建参数处理器
        this.parameterHandler = 
            conf.newParameterHandler(...);
    	
        // 2、构建结果集处理器
        this.resultSetHandler = 
        	conf.newResultSetHandler(...);
    } 
}

对于参数处理器接口,相对简单,只有1个默认实现类 DefaultParameterHandler ,该接口只有两个方法,分别是:

Mybatis最硬核的API是什么

// 有2个处理器会使用,分别是:
// 预编译处理器 PreparedStatementHandler
// 存储过程处理器 CallableStatementHandler

public void parameterize(Statement statement) {
   
    
    //使用ParameterHandler对象来完成对Statement的设值
    parameterHandler.setParameters(statement);
}

应用场景例如查询用户对象时,设置姓名,参数处理器结合类型处理器把 name 属性占位符进行赋值。

<select id="queryUSer">
    select * from t_user where name = #{name}
</select>
// 默认结果集处理器
public class DefaultResultSetHandler{
   
   
    // 处理输出参数
    public void handleOutputParameters(...) {
   
    
        // 获取参数
        final Object parameterObject = 
            parameterHandler.getParameterObject();
    
    	// 其它存储过程输出参数处理逻辑...
	}    
}

Mybatis最硬核的API是什么

10、ResultSetHandler – 结果集处理器

ResultSetHandler 是一个结果集处理器接口,它负责负责将 JDBC 返回的结果集 resultSet 对象转换为 List 类型的集合,是在语句处理器构建实例时被同时创建,底层做数据转换的工作会交给类型转换器 TypeHandler,它有1个默认实现类 DefaultResultSetHandler,该接口有3个方法,分别是:

Mybatis最硬核的API是什么

结果集处理器对于 JDBC 返回的结果集的基本处理,是先获取我们在映射器 Mapper 中指定 resultType 或 resultMap 映射关系,然后遍历解析结果集中的每一列数据,底层通过 MetaObject 对象做相关的反射处理。

对于详细的源码逻辑,我们后续源码剖析部分详细讲。

不讲不是中国人 O(∩_∩)O ~

Mybatis最硬核的API是什么

11、TypeHandler – 类型转换器

TypeHandler 是一个类型转换器/处理器接口,它负责 Java 数据类型和 JDBC 数据类型之间的映射与转换,当对 Statement 对象设置参数时,由 JavaType 转换为 JdbcType,当对 Statement 返回结果集进行封装映射时,又会将 JdbcType 转换为 JavaType。

Mybatis最硬核的API是什么

一般,我们可以直接使用 Mybatis 内置的类型处理器,简单看了一下有 65+ 个,当然我们是可以根据业务需要自定义类型处理器的,以便处理复杂类型或非标类型。

具体做法为:

1、实现 org.apache.ibatis.type.TypeHandler 接口;

2、继承 org.apache.ibatis.type.BaseTypeHandler 类。

其中 BaseTypeHandler 类作为抽象类就已经实现了 TypeHandler 接口。

我们看到接口 TypeHandler 定义了四个方法:

public interface TypeHandler<T> {
   

  // 设置参数
  void setParameter(
      PreparedStatement ps, 
      int i, T parameter, 
      JdbcType jdbcType);

  // 根据列名获取转换结果
  T getResult(ResultSet rs, String columnName);

  // 根据列下标获取转换结果
  T getResult(ResultSet rs, int columnIndex);

  // 根据列下标获取【存储过程】的输出结果
  T getResult(CallableStatement cs, int columnIndex);

}

其实,我之前在介绍 Mybatis 核心配置的时候,有大力介绍过类型处理器,没必要重复写(其实是懒),感兴趣的朋友可以直接看我们之前的文章 **《Mybatis系列全解(四):全网最全!Mybatis配置文件XML全貌详解》**中对类型处理器 TypeHandler 的介绍。

Mybatis最硬核的API是什么

12、MappedStatement – 语句对象

MappedStatement 语句对象,就是我们在映射器 Mapper 中维护的每一条语句,例如 <select|update|delete|insert>,Mybatis 中通过语句构造器 XMLStatementBuilder 对每一个语句进行解析:

Mybatis最硬核的API是什么

整个解析过程分为4步骤:

// Configuration 配置解析器
public class XMLConfigBuilder{
   
    
    // 解析映射器
    private void mapperElement(){
   
        
        // 创建映射器解析实例
        XMLMapperBuilder mapperParser = 
            new XMLMapperBuilder(...);
        
        // 开始解析
        mapperParser.parse();
    }
}

2、映射对象解析器 XMLMapperBuilder 解析语句

// 映射对象解析器
public class XMLMapperBuilder{
   
    
    // 1、解析入口
    public void parse() {
    
        
        // 解析映射器文件
        configurationElement(
            parser.evalNode("/mapper"));
    }
    
    // 2、节点解析
    private void configurationElement(XNode context) {
   
        
        // 构建语句对象
        buildStatementFromContext(
            context.evalNodes(
                "select|insert|update|delete"));
    }
    
    // 3、最终调用语句解析器
    private void buildStatementFromContext(){
   
        
        // 创建语句解析实例
        XMLStatementBuilder statementParser = 
            new XMLStatementBuilder();
        
        // 解析语句节点
        statementParser.parseStatementNode();
    }
}

3、语句解析器 XMLStatementBuilder 解析每一个节点

// 语句解析器
public class XMLStatementBuilder{
   
    
    // 解析语句节点
    public void parseStatementNode() {
   
        
        // 通过语句辅助类构建语句对象
        builderAssistant.addMappedStatement(...)
    }
}

4、语句辅助类 MapperBuilderAssistant 添加进语句集合中

// 语句辅助类
public class MapperBuilderAssistant{
   
    
    // 添加语句对象
    public MappedStatement addMappedStatement(
         
        // 最终添加到配置类的语句集合中
    	configuration.addMappedStatement(statement);
    }
}

Mybatis最硬核的API是什么

13、SqlSource – SQL源

SqlSource 是一个 SQL 源接口,它会结合用户传递的参数对象 parameterObject,动态地生成 SQL 语句,并最终封装成 BoundSql 对象。SqlSource 接口有5个实现类,分别是:StaticSqlSource、DynamicSqlSource、RawSqlSource、ProviderSqlSource、VelocitySqlSource(这只是一个测试用例,而非真正模板 Sql 源实现类)。

Mybatis最硬核的API是什么

SqlSource 实例在配置类 Configuration 解析阶段就被创建,Mybatis 框架会依据3个维度的信息来选择构建哪种数据源实例:

SqlSource 接口只有一个方法 getBoundSql ,就是创建 BoundSql 对象。

public interface SqlSource {
   

  BoundSql getBoundSql(Object parameterObject);

}

Mybatis最硬核的API是什么

14、BoundSql – SQL语句

BoundSql 对象存储了动态生成的 SQL 语句以及相应的参数信息,BoundSql 对象是在执行器具体执行 CURD 时通过实际的 SqlSource 实例所构建。通过 BoundSql 能够获取到实际数据库执行的 SQL 语句,系统可根据 SQL 语句构建 Statement 或者 PrepareStatement 。

public class BoundSql {
   

  //该字段中记录了SQL语句,该SQL语句中可能含有"?"占位符
  private final String sql;
    
  //SQL中的参数属性集合
  private final List<ParameterMapping> parameterMappings;
    
  //客户端执行SQL时传入的实际参数值
  private final Object parameterObject;
    
  //复制 DynamicContext.bindings 集合中的内容
  private final Map<String, Object> additionalParameters;
    
  //通过 additionalParameters 构建元参数对象
  private final MetaObject metaParameters;
    
}

到此,相信大家对“Mybatis最硬核的API是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. Mybatis是什么?Mybatis的前身又是什么?
  2. MyBatis 之Result Maps最精华部分

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mybatis api

上一篇:如何使用Nacos实现服务注册与发现

下一篇:vuejs怎么添加链接

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》