MyBatis-Plus 入门到实战,极简实现单表 CRUD

一、MyBatis-Plus 核心认知

1.1 什么是 MyBatis-Plus

MyBatis-Plus(简称 MP)是国内「苞米豆」团队开发的 MyBatis 增强工具,核心理念是只做增强、不做改变:

  • 基于 MyBatis 扩展,引入后不影响原有 MyBatis 代码逻辑;
  • 专注解决单表 CRUD 重复编码问题,无需手写 XML / 注解 SQL,大幅提升开发效率。

1.2 核心特性(对比原生 MyBatis 优势)

表格

特性 说明
无侵入性 完全兼容 MyBatis,无需修改现有工程代码
通用 CRUD 封装 内置 BaseMapper/IService,继承即拥有全量单表 CRUD 方法
主键自动生成 支持自增、雪花算法、UUID 等 4+ 主键策略,解决分布式 ID 问题
Lambda 条件构造 用 Lambda 写查询条件,避免硬编码字段名导致的错误
丰富内置功能 物理分页、性能分析、逻辑删除、乐观锁、代码生成器等
多数据库兼容 支持 MySQL/Oracle/SQLServer 及达梦、人大金仓等国产数据库

1.3 适用场景与多表处理

  • 核心场景:单表 CRUD(开发中 80% 以上的数据库操作场景);
  • 多表处理方案 :
    1. 沿用 MyBatis 方式:编写 XML 文件实现关联查询;
    2. Service 层组装:通过多次单表条件查询,手动拼接关联数据。

二、快速集成 MP(Spring Boot + MySQL)

前置条件

  1. JDK 8+、IDEA/Eclipse、Maven;
  2. 熟悉 Spring Boot 基础配置;
  3. 本地安装 MySQL 并创建测试数据库(如 boot)。

步骤 1:创建数据库与测试表

sql

复制代码
-- 删除原有表(避免冲突)
DROP TABLE IF EXISTS user;

-- 创建 user 表
CREATE TABLE user (
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);

-- 插入测试数据
DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

步骤 2:引入核心依赖(pom.xml)

⚠️ 注意:不要同时导入 MyBatis 和 MP 依赖,避免版本冲突!

xml

复制代码
<!-- MySQL 驱动(适配 MySQL 8+) -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

<!-- Lombok:简化实体类(省去 get/set/构造方法) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

<!-- MyBatis-Plus 启动器(核心依赖) -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
</dependency>

步骤 3:配置数据库连接(application.properties)

properties

复制代码
# 数据源配置
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 注意修改数据库名(boot)、用户名(root)、密码(root)
    url: jdbc:mysql://localhost:3306/boot?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: root

# 可选:配置 MP 日志(控制台打印自动生成的 SQL)
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

步骤 4:编写核心代码(实体类 + Mapper 接口)

4.1 实体类 User(与数据库表映射)

使用 Lombok 注解简化代码,字段与数据库列一一对应:

复制代码
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 用户实体类
 * 对应数据库 user 表
 */
@Data // 自动生成 get/set/toString/hashCode/equals 方法
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor  // 无参构造方法
public class User {
    private Long id;      // 主键ID(对应数据库 id 字段)
    private String name;  // 姓名(对应数据库 name 字段)
    private Integer age;  // 年龄(对应数据库 age 字段)
    private String email; // 邮箱(对应数据库 email 字段)
}
4.2 Mapper 接口 UserMapper(核心!无需手写 CRUD 方法)

只需继承 MP 的 BaseMapper<T> 接口,即可自动获得全量单表 CRUD 方法:

复制代码
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mp.pojo.User;
import org.apache.ibatis.annotations.Mapper;

/**
 * 用户 Mapper 接口
 * 继承 BaseMapper<User> 后,自动拥有单表 CRUD 方法
 */
@Mapper // 标识为 MyBatis Mapper 接口(可替换为启动类的 @MapperScan)
public interface UserMapper extends BaseMapper<User> {
    // 无需编写任何方法,BaseMapper 已封装所有单表操作
}
可选:批量扫描 Mapper(替代 @Mapper 注解)

在 Spring Boot 启动类添加 @MapperScan,指定 Mapper 包路径,无需每个接口加 @Mapper:

复制代码
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Spring Boot 启动类
 */
@MapperScan("com.mp.mapper") // 扫描 com.mp.mapper 包下所有 Mapper 接口
@SpringBootApplication
public class MpDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(MpDemoApplication.class, args);
    }
}

步骤 5:测试 MP 的 CRUD 功能

编写 Spring Boot 测试类,注入 UserMapper 直接调用内置方法:

复制代码
import com.mp.mapper.UserMapper;
import com.mp.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

/**
 * MP 基础 CRUD 测试
 */
@SpringBootTest // 标识为 Spring Boot 测试类
public class MpBasicTest {

    // 自动注入 UserMapper(Spring 容器管理)
    @Autowired
    private UserMapper userMapper;

    /**
     * 测试:查询所有用户
     * selectList(null):null 表示无查询条件,查询全表
     */
    @Test
    public void testSelectAll() {
        List<User> userList = userMapper.selectList(null);
        // 遍历输出所有用户
        userList.forEach(System.out::println);
    }
}
执行结果

控制台输出数据库中 5 条用户数据,同时打印 MP 自动生成的 SQL:

plaintext

复制代码
==>  Preparing: SELECT id,name,age,email FROM user
==> Parameters:
<==    Columns: id, name, age, email
<==        Row: 1, Jone, 18, test1@baomidou.com
<==        Row: 2, Jack, 20, test2@baomidou.com
<==        Row: 3, Tom, 28, test3@baomidou.com
<==        Row: 4, Sandy, 21, test4@baomidou.com
<==        Row: 5, Billie, 24, test5@baomidou.com
<==      Total: 5

User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)

三、解决实体类与数据库表 / 字段不一致问题

实际开发中,实体类名 / 字段名常与数据库表名 / 列名不一致,通过 MP 注解快速解决:

3.1 表名不一致:@TableName

作用:指定实体类对应的数据库表名。示例:实体类 SysUser 对应数据库表 sys_user:

复制代码
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("sys_user") // 显式指定数据库表名
public class SysUser {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

3.2 字段名不一致:@TableField

作用:指定实体类字段对应的数据库列名。示例:实体类字段 userName 对应数据库列 user_name:

复制代码
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("sys_user")
public class SysUser {
    private Long id;
    
    @TableField("user_name") // 字段 userName 对应列 user_name
    private String userName;
    
    private Integer age;
    
    @TableField("user_email") // 字段 userEmail 对应列 user_email
    private String userEmail;
}

四、核心扩展:BaseMapper 内置常用 CRUD 方法

表格

方法名 功能说明 示例
selectList(Wrapper) 根据条件查询多条数据 selectList(null) → 查询全表
selectById(主键) 根据主键查询单条数据 selectById(1L) → 查询 id=1
insert(实体) 新增数据 insert(new User(null, "Lucy", 22, "lucy@test.com"))
updateById(实体) 根据主键更新数据 updateById(new User(1L, "Jone", 19, "test1@baomidou.com"))
deleteById(主键) 根据主键删除数据 deleteById(5L) → 删除 id=5
selectCount(Wrapper) 根据条件统计数量 selectCount(null) → 统计全表行数

五、总结

核心要点

  1. MP 定位:MyBatis 增强工具,无侵入、专注简化单表 CRUD,多表操作仍可沿用 MyBatis 方式;
  2. 核心简化点 :继承 BaseMapper<T> 即可获得全量单表 CRUD 方法,无需手写 SQL;
  3. 关键配置 :
    • 日志配置:通过 mybatis-plus.configuration.log-impl 查看自动生成的 SQL,方便调试;
    • 映射注解:@TableName 解决表名不一致,@TableField 解决字段名不一致;
  4. 集成流程:建库建表 → 引入依赖 → 配置数据源 → 编写实体类 / Mapper → 测试 CRUD。

后续进阶方向

  1. 主键生成策略(雪花算法、自增等);
  2. Lambda 条件构造器(复杂条件查询);
  3. 分页查询(物理分页,替代 MyBatis 分页插件);
  4. 逻辑删除(软删除,保留数据记录);
  5. 通用 Service(IService/ServiceImpl,封装更上层的业务逻辑)。
相关推荐
wljt14 小时前
公司二-面试题
java·开发语言·mybatis
VimorphTech17 小时前
文本已经改了,旧的音频生成结果还能回写吗?
java·数据库·mybatis
麻瓜code1 天前
双写一致性:为什么是“删缓存“,而不是“改缓存“
java·缓存·mybatis
郭小李2 天前
mybatis 动态 sql
java·sql·mybatis
知守观2 天前
技术考古:iBATIS 2.3.4 时代的持久层,是如何用 Map 玩转 307 个存储过程的?
java·后端·mybatis
captain3762 天前
MyBatis Plus(1)
java·服务器·mybatis
代码不停2 天前
MyBatis进阶
spring boot·mybatis
captain3762 天前
MyBatis(入门5)其他查询操作
java·数据库·spring boot·mybatis
captain3762 天前
MyBatis(进阶1)
mybatis
郭小李3 天前
mybatis的 Mapper.xml语法
xml·java·mybatis