MyBatis 开发模式演进:原生、Spring 与 Spring Boot 整合实战(MyBatis系列2)

通过对比原生 MyBatis、Spring 整合 MyBatis、Spring Boot 整合 MyBatis 三种模式,深入理解 MyBatis 核心原理与框架自动化简化的演进过程。

一、原生 MyBatis:手动配置,手动执行

原生 MyBatis 的使用可以概括为两大层次:

  • 配置层 :编写 MyBatis 主配置文件(mybatis-config.xml),完成三件事:引入 jdbc.properties 加载数据库四要素;配置别名实现自动映射;扫描 Mapper 包自动生成代理对象。
  • 执行层 :在业务代码中手动加载配置 → 创建 SqlSession → 获取 Mapper 代理 → 执行 SQL → 必须手动关闭连接

1.1 环境准备

复制代码
<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.9</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
    </dependency>
</dependencies>

1.2 配置文件

jdbc.properties:数据库四要素

复制代码
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/yourdb?serverTimezone=UTC&useSSL=false
jdbc.username=root
jdbc.password=123456

② 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配置文件 -->
    <properties resource="jdbc.properties"/>

     <!-- 别名扫描的包路径 -->
    <typeAliases>
        <package name="com.example.pojo"/>
    </typeAliases>

     <!-- 数据源 -->
    <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>
    </environments>

    <!-- 映射文件扫描包路径 -->
    <mappers>
        <package name="com.example.mapper"/>
    </mappers>
</configuration>

1.3 基础代码

实体类 User.java

复制代码
package com.example.pojo;

public class User {
    private Integer id;
    private String name;

    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    @Override
    public String toString() {
        return "User{id=" + id + ", name='" + name + "'}";
    }
}

Mapper 接口(注解版)UserMapper.java

复制代码
package com.example.mapper;

import com.example.pojo.User;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {
    @Select("select * from user where id = #{id}")
    User findById(Integer id);
}

1.4 手动执行 SQL

复制代码
package com.example;

import com.example.mapper.UserMapper;
import com.example.pojo.User;
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.InputStream;

public class MyBatisTest {
    public static void main(String[] args) throws Exception {
            // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 2. 加载SqlMapConfig.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        // 3. 创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        // 4. 获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 5. 执行SqlSession对象执行查询,获取结果
        AccountDao accountDao = sqlSession.getMapper(UserMapper.class);
        Account ac = accountDao.findById(1);
        System.out.println(user);
        // 6. 释放资源
        sqlSession.close();
    }
}

二、Spring 整合 MyBatis:配置类接管,自动注入

当 MyBatis 整合到 Spring 后,之前繁琐的手动步骤被 Spring 完全接管:

  • 配置层 :XML 配置被拆分为 JdbcConfig(创建 DataSource)和 MybatisConfig(配置别名、扫描 Mapper)。
  • 执行层 :Spring 容器自动管理 SqlSession 的生命周期,直接注入 Mapper 接口即可,无需手动打开/关闭连接

2.1 环境准备(添加 Spring 依赖)

复制代码
<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.9</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.7</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.20</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.8</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
    </dependency>
</dependencies>

2.2 配置文件(仅保留 jdbc.properties

复制代码
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/yourdb?serverTimezone=UTC&useSSL=false
jdbc.username=root
jdbc.password=123456

2.3 Java 配置类

① 总配置入口 SpringConfig.java

复制代码
package com.example.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;

@ComponentScan("com.example")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class, MybatisConfig.class})
public class SpringConfig {
}

② 数据源配置 JdbcConfig.java

复制代码
package com.example.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;

public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String userName;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}

③ MyBatis 配置 MybatisConfig.java
1.@Mapper 是 MyBatis 注解,作用:标记当前接口为 Mapper,生成代理对象。
2.@MapperScan / MapperScannerConfigurer 作用:批量扫描包下所有接口,自动当作 Mapper,自动生成代理。
3.只要配置了批量扫描,接口上就不需要写 @Mapper;写了也不报错,但多余。

复制代码
package com.example.config;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;

@MapperScan("com.example.mapper")
public class MybatisConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        // 设置数据源(自动注入Spring管理的DruidDataSource)
        factoryBean.setDataSource(dataSource);
        // 设置模型类的别名扫描包
        factoryBean.setTypeAliasesPackage("com.example.pojo");
        return factoryBean;
    }
}

或者

复制代码
public class MybatisConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        //设置模型类的别名扫描
        ssfb.setTypeAliasesPackage("com.example.pojo");
        //设置数据源
        ssfb.setDataSource(dataSource);
        return ssfb;
    }

    //定义bean,返回MapperScannerConfigurer对象
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.example.mapper");
        return msc;
    }
}

2.4 Service 层与主程序

复制代码
package com.example.service;

import com.example.mapper.UserMapper;
import com.example.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User findUserById(Integer id) {
        return userMapper.findById(id);
    }
}

package com.example;

import com.example.config.SpringConfig;
import com.example.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = ctx.getBean(UserService.class);
        System.out.println(userService.findUserById(1));
    }
}

三、Spring Boot 整合 MyBatis:自动装配,极简开发

Spring Boot 对 MyBatis 进行了深度自动化封装,基于自动装配原理,完全省略手动配置,是企业级开发的主流方案:

  • 配置层:无需编写配置类/XML,仅需在配置文件中声明数据库连接信息,Spring Boot 自动完成数据源、SqlSessionFactory、Mapper 代理的创建。
  • 执行层:零手动操作,直接通过注解注入 Mapper,Spring Boot 全权管理 SqlSession 生命周期、资源释放与事务。

3.1 环境准备(Starter 自动依赖)

复制代码
<dependencies>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.3.0</version>
    </dependency>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

3.2 核心配置文件(application.yml)

仅需4行数据库配置,无任何额外配置

复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/yourdb?serverTimezone=UTC&useSSL=false
    username: root
    password: 123456

MyBatis 扩展配置(可选,简化实体类别名)

mybatis:

type-aliases-package: com.example.pojo

3.3 基础代码

实体类 User.java(与原生、Spring 版本完全一致,无需修改)

Mapper 接口(添加 @Mapper 注解,交由 Spring 管理)

复制代码
package com.example.mapper;

import com.example.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

// @Mapper:MyBatis 注解,Spring Boot 自动扫描并创建代理对象
@Mapper
public interface UserMapper {
    @Select("select * from user where id = #{id}")
    User findById(Integer id);
}

3.4 Service 层与启动类

Service 层(纯注解注入,无任何变化)

复制代码
package com.example.service;

import com.example.mapper.UserMapper;
import com.example.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User findUserById(Integer id) {
        return userMapper.findById(id);
    }
}

Spring Boot 启动类(项目入口,自动加载容器)

复制代码
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 自动装配核心注解,扫描所有组件
@SpringBootApplication
public class MyBatisSpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyBatisSpringBootApplication.class, args);
    }
}

3.5 测试类

复制代码
package com.example;

import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

// Spring Boot 测试注解,自动加载容器
@SpringBootTest
public class SpringBootTest {
    @Autowired
    private UserService userService;

    @org.junit.Test
    public void testFindById(){
        System.out.println(userService.findUserById(1));
    }
}

四、核心思想总结与对比

层次 原生 MyBatis Spring 整合 MyBatis Spring Boot 整合 MyBatis
配置 XML 文件(mybatis-config.xml + jdbc.properties Java 配置类(JdbcConfig + MybatisConfig application.yml,仅数据库配置
数据源 硬编码在 XML 中或通过 <properties> 引入 独立的 DataSource Bean,可灵活替换 自动装配,无需手动创建
代理生成 通过 <mappers> 扫描包 @MapperScan 注解,代理对象自动注册为 Spring Bean @Mapper 注解,自动扫描注册
连接管理 手动 openSession()close() Spring 自动管理,无需手动操作 Spring Boot 全自动管理
事务 手动提交或自动提交(openSession(true) 可结合 @Transactional 声明式事务 开箱即用,@Transactional 直接生效

原生 MyBatis 核心要点回顾

  • 配置层mybatis-config.xml 中引入 jdbc.properties → 配置别名包 → 扫描 Mapper 包生成代理。
  • 执行层 :手动构建 SqlSessionFactory → 打开 SqlSession → 获取代理 → 执行 SQL → 手动关闭连接

Spring 整合 MyBatis 核心替代

  • 配置替代@PropertySource 加载 jdbc.properties@Bean 创建 DataSource@MapperScan 替代手动扫描,SqlSessionFactoryBean 替代手动构建工厂。
  • 执行替代 :Spring 在运行时自动打开/关闭 SqlSession,Mapper 代理直接注入 Service,主程序只需获取容器、调用业务方法。

Spring Boot 整合 MyBatis 核心优势

  • 自动装配:Starter 自动整合所有依赖,无需手动管理版本。
  • 零配置开发:无需编写配置类、XML,仅需声明数据库信息。
  • 全自动化管理:数据源、工厂、会话、事务全部由 Spring Boot 自动处理。

📌 核心结论

Spring 整合 MyBatis 的本质,是将原生 MyBatis 中繁琐的手动步骤(配置加载、连接管理、资源释放)交由 Spring 的 IoC 和 AOP 自动化处理;Spring Boot 整合 MyBatis 则是在 Spring 基础上的进一步自动化封装,实现真正的"配置驱动,业务无感",是企业开发的最优方案。

相关推荐
java1234_小锋25 分钟前
Java高频面试题:MyBatis如何实现动态数据源切换?
java·开发语言·mybatis
秋风不问归客1 小时前
Springboot面试全面整理
spring boot·后端·面试
卓怡学长1 小时前
m319个人网站的设计与实现
java·数据库·spring·tomcat·maven·intellij-idea
砍材农夫4 小时前
spring-ai 第五模型介绍
java·人工智能·spring
mu_guang_4 小时前
计算机体系结构2-内存一致性
java·后端·spring·计算机体系结构
小旭95274 小时前
SpringBoot + 七牛云 + Quartz:图片存储与定时清理
java·spring boot·后端·mybatis
橘子编程5 小时前
计算机内存与缓存完全指南
java·计算机网络·spring·缓存
杰克尼5 小时前
springCloud(day09-Elasticsearch02)
java·后端·spring·spring cloud
云烟成雨TD5 小时前
Spring AI 1.x 系列【24】结构化输出 API
java·人工智能·spring
han_hanker5 小时前
springboot 不推荐使用@Autowired怎么处理
java·spring boot·后端