MyBatis -- 执行流程

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MyBatis的执行流程可以概括为: 读取核心配置文件 - 创建会话工厂 - 创建会话 - 将Mapper接口和Mapper映射文件做映射,获取Mapper实例对象 - 执行Mapper对象方法

传统JDBC开发

代码样例

import java.sql.*;

public class JdbcExample {
   
    public static void main(String[] args) {
   
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");

            // 创建Statement对象
            stmt = conn.createStatement();

            // 执行查询
            String sql = "SELECT * FROM mytable";
            rs = stmt.executeQuery(sql);

            // 处理结果集
            while (rs.next()) {
   
                int id = rs.getInt("id");
                String name = rs.getString("name");
                ();
        } finally {
   
            // 关闭连接、Statement和结果集
            try {
   
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
   
                e.printStackTrace();
            }
        }
    }
}
  • 我们可以看到,JDBC不具备良好的扩展性,代码都是写死的,当需要改变数据库连接信息或sql语句时,就需要对代码进行改动
  • 对结果集的解析比较繁琐
  • 连接和释放资源的工作量较大,可能导致性能问题,并且编写的代码量也大

因此MyBatis的到来就是为了弥补JDBC的缺点

MyBatis执行流程

MyBatis是怎么优化JDBC的呢?

包括如下几个方面:

  1. JDBC数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,MyBatis使用数据库链接池解决此问题
  2. JDBC将SQL语句写在代码中造成代码不易维护,SQL变动需要改变Java代码,MyBatis将SQL语句配置在XML文件中与Java代码分离可以解决此问题
  3. JDBC向SQL语句传参数麻烦,因为SQL语句的WHERE条件不一定,可能多也可能少,占位符需要和参数一一对应,MyBatis自动将Java对象映射至SQL语句,通过statement中的parameterType定义输入参数的类型解决此问题
  4. JDBC对结果集解析麻烦,SQL变化导致解析代码变化,且解析前需要遍历,MyBatis自动将SQL执行结果映射至Java对象,通过statement中的resultType定义输出结果的类型解决此问题

那优化后的MyBatis的具体执行流程是怎么样的呢?

第一步 - 读取MyBatis核心配置文件 mybatis-config.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>
    <!-- 配置数据库连接信息 -->
    <properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis_db"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </properties>

    <!-- 配置mapper -->
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

上面是一个 mybatis-config.xml 代码样例,mybatis-config.xml主要包含了俩部分内容

  • 配置了一个MySQL数据库,并指定了数据库驱动程序、URL、用户名和密码
  • 指定了一个名为UserMapper.xml的mapper文件,它位于com/example/mapper包中

在MyBatis中,mybatis-config.xml 由SqlSessionFactoryBuilder负责读取解析,下面会讲到

创建会话工厂SqlSessionFactory

SqlSessionFactory 是 MyBatis 中的核心对象,每个 SqlSessionFactory 对象都代表一个数据库实例,且全局只有一个

SqlSessionFactory 通过 SqlSessionFactoryBuilder 对象构建,SqlSessionFactoryBuilder 会根据 mybatis-config.xml配置文件的信息构建出 SqlSessionFactory 的实例

如下代码

// 创建 SqlSessionFactoryBuilder 对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 加载配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");

// 构建 SqlSessionFactory 对象
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);

// 关闭配置文件流
inputStream.close();

SqlSessionFactory 的主要作用是创建 SqlSession 对象

创建会话SqlSession

SqlSession是 MyBatis 中执行持久化操作的对象。它类似于JDBC中的Connection,一个线程一个SqlSession

SqlSession包含了所有执行SQL操作的方法

通过SqlSession执行SQL操作的代码实例

// 获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();

// 执行查询操作
try {
   
    // 获取映射器接口
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    // 调用映射器接口的方法执行查询操作
    List<User> users = userMapper.getAllUsers();

    // 处理查询结果
    for (User user : users) {
   
        System.out.println(user.getId() + " - " + user.getName());
    }
} finally {
   
    // 关闭SqlSession
    sqlSession.close();
}

我们看到,往 sqlSession.getMapper 传入UserMapper接口后,得到的确实一个 userMapper 对象,这是怎么做到的呢?

  1. 在调用SqlSession的getMapper方法时,传入Mapper接口的Class对象
  2. 在SqlSession的getMapper方法内部,会根据传入的Mapper接口的Class对象,动态创建一个代理对象
  3. 在代理对象中,会将SqlSession对象作为参数传递给所有的Mapper方法,这样就可以在Mapper方法中调用SqlSession的方法执行数据库操作,我们上面说了SqlSession包含了所有执行SQL操作的方法
  4. 在代理对象创建完成后,会将这个代理对象返回给调用方,这样就可以使用这个代理对象来调用Mapper接口中的方法了

看到这里,我们已经成功执行了SQL语句

但是最后有一个问题,SqlSession为什么能包含所有执行SQL操作的方法呢?

我在另外一篇博客中进行进行了说明,地址如下:
MyBatis核心 - SqlSession如何通过Mapper接口生成Mapper对象

目录
相关文章
|
3月前
|
人工智能 Java 数据库连接
Mybatis执行流程
本文详细分析了 MyBatis 的执行流程,介绍了其核心组件如 SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession 的作用与实现原理,并通过源码解析了 SQL 语句的执行过程,包括动态代理、缓存机制及数据库查询的实现,帮助读者深入理解 MyBatis 的内部工作机制。
100 0
Mybatis执行流程
|
7月前
|
SQL XML Java
一、MyBatis简介:MyBatis历史、MyBatis特性、和其它持久化层技术对比、Mybatis下载依赖包流程
一、MyBatis简介:MyBatis历史、MyBatis特性、和其它持久化层技术对比、Mybatis下载依赖包流程
262 69
|
SQL XML Java
MyBatis 动态SQL全流程解析
动态SQL概述 动态SQL是MyBatis 强大功能之一,他免除了在JAVA代码中拼装SQL字符串麻烦,同时保留了我们对SQL的自主控制,更方便进行SQL性能优化改造。 动态SQL中我们使用XML 脚本元素控制SQL的拼装,这都是日常开发中要用到元素,我们一起来回顾一下 if choose (when, otherwise) trim (where, set) foreach if <if test="title != null"> AND title like #{title} </if> 1 2 3 在if元素中通过test接受一个OGNL逻辑表达式,可作常规的逻辑计算如:
392 0
|
Java 关系型数据库 数据库连接
MyBatis 执行流程分析
MyBatis 执行流程分析
|
SQL XML 缓存
mybatis执行流程
mybatis执行流程
220 0
|
Java 数据库连接 数据库
MyBatis 核心对象及工作流程?
MyBatis 核心对象及工作流程?
100 0
|
SQL XML Java
MyBatis初探:揭示初始化阶段的核心流程与内部机制
MyBatis初探:揭示初始化阶段的核心流程与内部机制
130 2
MyBatis初探:揭示初始化阶段的核心流程与内部机制
|
Java 关系型数据库 数据库连接
MyBatis 执行流程分析
MyBatis 执行流程分析
133 2
|
SQL Java 数据库连接
|
SQL 缓存 Java
MyBatis Plus插件机制与执行流程原理分析
MyBatis Plus插件机制与执行流程原理分析
564 0