通过对比原生 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 基础上的进一步自动化封装,实现真正的"配置驱动,业务无感",是企业开发的最优方案。