SpringBoot 集成 MyBatis 与 MyBatis-Plus 详解
SpringBoot 集成 MyBatis 和 MyBatis-Plus 的完整流程。涵盖基础组件回顾、环境准备、依赖引入、配置文件设置、Mapper 接口编写及注解使用。MyBatis-Plus 部分介绍了核心优势、Lombok 集成、常用注解(@TableName, @TableId, @TableField)及条件构造器(Wrapper)的使用示例,帮助开发者快速实现 CRUD 操作。

SpringBoot 集成 MyBatis 和 MyBatis-Plus 的完整流程。涵盖基础组件回顾、环境准备、依赖引入、配置文件设置、Mapper 接口编写及注解使用。MyBatis-Plus 部分介绍了核心优势、Lombok 集成、常用注解(@TableName, @TableId, @TableField)及条件构造器(Wrapper)的使用示例,帮助开发者快速实现 CRUD 操作。

MyBatis 作为一款优秀的持久层框架,以其灵活的 SQL 定制能力和低侵入性成为 Java 开发中主流的 ORM 方案。而 SpringBoot 凭借'约定优于配置'的理念,大幅简化了项目搭建和配置流程。本文将从 MyBatis 基础回顾入手,一步步讲解 SpringBoot 集成 MyBatis、MyBatis-Plus 的完整流程,同时补充 Lombok、核心注解、常见配置等关键知识点。
MyBatis 是一款半自动化的 ORM(对象关系映射)框架,它摒弃了传统 JDBC 的硬编码式 SQL 操作,将 SQL 语句与 Java 代码解耦,支持 XML 或注解两种方式编写 SQL,同时提供结果映射、参数绑定等核心功能。
MyBatis-Boot 是 MyBatis 官方提供的 SpringBoot 集成组件(mybatis-spring-boot-starter),核心目标是简化 MyBatis 在 SpringBoot 项目中的配置,实现'零配置'快速集成。
application.properties 或 application.yml。
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/<database_name>?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
# 1. 指定 MyBatis 全局配置文件路径(mybatis-config.xml),可配置全局参数(如缓存、插件、驼峰转换等)
mybatis.config-location=classpath:mybatis-config.xml
# 2. 指定 MyBatis Mapper 映射文件(XML)的扫描路径,匹配 classpath 下 mybatis/mapper 目录下的所有 .xml 文件
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
# 3. 指定实体类包路径,配置后在 XML 中可直接使用实体类名代替全类名
mybatis.type-aliases-package=com.example.entity
@MapperScan,SpringBoot 启动时就会扫描该路径下的 Mapper。resources/mybatis 目录下添加 mybatis-config.xml,配置一些全局属性。
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="autoMappingBehavior" value="FULL"/>
</settings>
public interface SysRoleMapper {
/* 查询所有角色信息 */
List<SysRole> getAll();
}
public class SysRole {
private Long id; //主键 ID
private String code; //角色编码
private String roleName; //角色名称
//省略 get/set...
}
resources/mybatis/mapper 目录下创建并编写 SysRoleMapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.SysRoleMapper">
<select resultType="com.example.entity.SysRole">
select * from sys_role
</select>
</mapper>
@Mapper 注解,建议直接使用上面的方式不然需要一个个在接口上添加注解。@SpringBootTest
public class SysRoleMapperTest {
@Autowired
private SysRoleMapper sysRoleMapper;
@Test
public void testSelectAll() {
List<SysRole> sysRoles = sysRoleMapper.getAll();
for (SysRole sysRole : sysRoles) {
System.out.println(sysRole);
}
}
}
运行效果:此处无法看到输出执行的 SQL,并且会输出其他日志信息,可以在 application.properties 中配置日志输出:
logging.level.root=warn
logging.level.com.example.mapper=trace
logging.pattern.console=%p%m%n
至此,SpringBoot 和 MyBatis 集成就完成了。
MyBatis-Plus(简称 MP)是基于 MyBatis 的增强工具,在保留 MyBatis 原有功能的基础上,实现了'无 SQL'CRUD、分页、逻辑删除、乐观锁等功能,大幅提升开发效率。
MyBatis-Plus 核心理念是'只做增强,不做改变',它封装了基础 CRUD 操作,无需编写 SQL 即可实现数据访问,同时支持自定义 SQL 扩展,完美兼容 MyBatis 原有代码。
Lombok 是一款 Java 开发插件,通过注解(如 @Data、@NoArgsConstructor)自动生成 getter/setter/构造器/toString 等代码,核心优势:
@Accessors(chain = true))。<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
// 链式调用(可选)
@Accessors(chain = true)
// 核心简化:getter/setter/toString/equals/hashCode + 无参构造
@Data
// 补充全参构造(@Data 不含全参)
@AllArgsConstructor
// 补充无参构造(若@Data 的@RequiredArgsConstructor 覆盖了无参,需显式声明)
@NoArgsConstructor
public class User {
private Long id;
private String username;
// 排除 toString 输出
@ToString.Exclude
private String password;
private Integer age;
}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/ktsms_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
logging.level.root=warn
logging.level.com.example.mapper=trace
logging.pattern.console=%p%m%n
将 MyBatis Starter 替换为 MyBatis-Plus Starter(无需额外引入 MyBatis 依赖):
<!-- MyBatis-Plus SpringBoot 集成包 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
在启动类中添加 Mapper 包的扫描,和之前 MyBatis 一样的操作。
@TableName 注解在类上,指定数据库表名 (实体名与表名不一致时需要指定)@TableId(type = IdType.AUTO) 注解在主键属性上,且指定主键生成策略为自动增长@TableField 注解在属性上,指定数据库字段名 (不满足默认匹配规则时需要指定)。属性和字段名默认匹配规则是全小写的属性对应同名的字段:采用骆驼命名规则的属性对应的字段名为两个单词之间使用_下划线连接,例如:usrName 属性默认对应的字段名为 usr_name。编写 Mapper 接口:
public interface SysRoleMapper extends BaseMapper<SysRole> { }
编写实体类 SysRole:
@Data
@NoArgsConstructor
@AllArgsConstructor
// 表名
@TableName("sys_role")
public class SysRole {
// 主键 ID, 自增
@TableId(type = IdType.AUTO)
private Long id;
//主键 ID
private String code; //角色编码
private String roleName; //角色名称
private Long createdUserId; //创建者
private Date createdTime; //创建时间
private Long updatedUserId; //修改者
private Date updatedTime; //修改时间
}
创建 SysRoleMapperTester.java:
@SpringBootTest
public class SysRoleMapperTest {
@Autowired
private SysRoleMapper sysRoleMapper;
@Test
public void testSelectAll() {
List<SysRole> sysRoles = sysRoleMapper.selectList(null);
for (SysRole sysRole : sysRoles) {
System.out.println(sysRole);
}
}
}
至此,SpringBoot 集成 MyBatis-Plus 完成,通过以上几个步骤我们就实现了 sysRole 查询所有数据的功能,基本的 CRUD 都能完成,几乎不用写 SQL 语句。
MyBatis Plus 如何知道我们要查询的是哪张表?表中有哪些字段呢?
MyBatis Plus 就是根据 PO 实体的信息来推断出表的信息,从而生成 SQL 的。默认情况下:
但很多情况下,默认的实现与实际场景不符,因此 MyBatis Plus 提供了一些注解便于我们声明表信息。
com.baomidou.mybatisplus.annotation.TableName指定实体类对应的数据库表名(解决实体类名与表名不一致的问题)。
| 属性名 | 类型 | 作用 |
|---|---|---|
| value | String | 表名(核心属性,可省略属性名直接写值) |
| schema | String | 数据库 schema(多租户 / 多 schema 场景) |
| keepGlobalPrefix | boolean | 是否保留全局表前缀(配合 mybatis-plus.global-config.db-config.table-prefix 使用) |
com.baomidou.mybatisplus.annotation.TableId标记实体类的主键字段,指定主键生成策略。
| 属性名 | 类型 | 作用 |
|---|---|---|
| value | String | 主键字段名(实体属性名与表主键字段名不一致时使用) |
| type | IdType(枚举) | 主键生成策略(核心属性) |
| 枚举值 | 作用 |
|---|---|
| AUTO | 数据库自增(需保证数据库表主键设置为自增) |
| NONE | 无策略(需手动设置主键值) |
| INPUT | 手动输入(与 NONE 类似,MP 不干预,需手动赋值) |
| ASSIGN_ID | 雪花算法生成主键(默认,支持 Long/Integer/String 类型,适合分布式场景) |
| ASSIGN_UUID | 生成 UUID(不含中划线,String 类型) |
| ID_WORKER | 已过时,等效 ASSIGN_ID(仅支持 Long 类型) |
| ID_WORKER_STR | 已过时,等效 ASSIGN_ID(String 类型) |
| UUID | 已过时,等效 ASSIGN_UUID |
com.baomidou.mybatisplus.annotation.TableField指定实体属性与数据库表字段的映射关系,支持排除字段、字段填充、忽略字段等功能。
| 属性名 | 类型 | 作用 |
|---|---|---|
| value | String | 字段名(实体属性名与表字段名不一致时使用) |
| exist | boolean | 是否为数据库表字段(默认 true,false 表示该属性非表字段) |
| fill | FieldFill(枚举) | 字段填充策略(新增 / 更新时自动填充,如创建时间、更新时间) |
| select | boolean | 查询时是否包含该字段(默认 true,false 表示查询时忽略) |
| insertStrategy | FieldStrategy(枚举) | 插入时的字段验证策略(如 NOT_NULL:非空才插入) |
| updateStrategy | FieldStrategy(枚举) | 更新时的字段验证策略(如 IGNORED:忽略空值,强制更新) |
| whereStrategy | FieldStrategy(枚举) | 作为查询条件时的验证策略 |
从以上步骤中,我们可以看到集成 MyBatis-Plus 非常的简单,只需要引入 starter 启动器,并配置 mapper 扫描路径即可。 但 MyBatis-Plus 的强大远不止这些功能,想要详细了解 MyBatis-Plus 的强大功能?那就继续往下看吧!
MyBatis 通用的 CRUD 功能都在 BaseMapper<T> 接口中:
条件构造器(Wrapper)是 MyBatis-Plus 实现动态 SQL 的核心,通过链式调用拼接 WHERE 条件,无需手动拼接 SQL 字符串,支持查询、更新、删除操作。
| 构造器类型 | 适用场景 | 核心特点 |
|---|---|---|
| QueryWrapper | 查询 / 删除条件构造 | 基础版,字段名硬编码 |
| UpdateWrapper | 更新条件构造 | 支持直接设置更新字段 |
| LambdaQueryWrapper | 查询 / 删除条件构造(Lambda) | 类型安全,避免字段名写错 |
| LambdaUpdateWrapper | 更新条件构造(Lambda) | 类型安全,无字段硬编码 |
| 方法 | 作用 | 示例 |
|---|---|---|
| eq | 等于 = | eq("age", 20) |
| gt/ge | 大于 >/ 大于等于≥ | gt("age", 18) |
| lt/le | 小于 < / 小于等于≤ | lt("age", 30) |
| like | 模糊查询 LIKE | like ("name", "张") |
| in | IN 条件 | in("id", Arrays.asList(1,2,3)) |
| orderByDesc | 降序排序 | orderByDesc("age") |
| select | 指定查询字段 | select("id", "name") |
| set | 更新字段赋值 | set("age", 21) |
QueryWrapper<User> wrapper = new QueryWrapper<User>()
.eq("user_name", "张三")
.gt("age", 18)
.like("email", "qq.com");
List<User> list = userMapper.selectList(wrapper);
UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
.eq("user_name", "张三")
.set("age", 22)
.setSql("age = age + 1"); // 支持 SQL 片段
userMapper.update(null, wrapper);
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
.eq(User::getUserName, "张三")
.gt(User::getAge, 18);
List<User> list = userMapper.selectList(wrapper);
.or() 方法即可。
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online