MyBatis-Plus:从入门到进阶

发布于:2025-06-26 ⋅ 阅读:(20) ⋅ 点赞:(0)

📌 摘要

在现代 Java 开发中,MyBatis-Plus 是基于 MyBatis 的增强工具,它在不改变 MyBatis 原有功能的基础上,提供了大量便捷的封装和扩展能力,极大提升了开发效率。

本文将带你从 MyBatis-Plus 基础语法高级特性 全面掌握这一高效 ORM 工具,内容涵盖:

  • MyBatis-Plus 简介与核心优势
  • 快速入门示例(Spring Boot 整合)
  • 核心功能详解(CRUD、QueryWrapper、LambdaQueryWrapper、自动分页等)
  • 高级特性(逻辑删除、乐观锁、多租户支持)
  • 实战案例解析
  • 性能优化建议与最佳实践
  • 常见面试题解析

适合初学者入门和中高级开发者提升技能。


🎯 一、为什么选择 MyBatis-Plus?

✅ MyBatis-Plus 的特点:

特性 描述
简化 CRUD 提供通用 Mapper 和 Service,减少重复代码
条件构造器 强大的 QueryWrapper、LambdaQueryWrapper 构建查询条件
自动分页 内置分页插件,一行代码实现分页
多租户支持 支持企业级多租户架构
逻辑删除 替代物理删除,软删除机制
乐观锁 支持版本控制,避免并发冲突
代码生成器 快速生成 Entity、Mapper、Service、Controller 等代码
无侵入性 不影响原有 MyBatis 使用方式

❗ 适用场景:

  • 对开发效率要求高,希望快速搭建模块
  • 数据结构清晰、表字段命名规范
  • 不想重复编写基础 CURD 方法
  • 希望使用 Lambda 表达式构建查询条件
  • 需要内置分页、逻辑删除等功能的企业项目

🧱 二、MyBatis-Plus 核心组件介绍

组件 描述
BaseMapper<T> 提供通用的 CRUD 接口
IService<T> / ServiceImpl<M,T> 封装业务逻辑接口和服务类
QueryWrapper<T> 条件构造器,用于构建 SQL 查询条件
LambdaQueryWrapper<T> 类型安全的 Lambda 表达式构建查询条件
Page<T> 分页对象,配合分页插件使用
@TableName 实体类与表名映射注解
@TableId 主键注解,指定主键类型和字段
@TableLogic 标记该字段为逻辑删除字段
@Version 标记该字段为乐观锁版本号字段
AutoGenerator 代码自动生成器,一键生成 Entity、Mapper、Service、Controller 等代码

🚀 三、快速入门:整合 Spring Boot + MyBatis-Plus

✅ 开发环境准备:

  • JDK 1.8+
  • Maven 3.x
  • MySQL 5.7+
  • Spring Boot 2.6+ 或 3.x(兼容)
  • IDE(如 IntelliJ IDEA)

1. 添加依赖(Maven):

<!-- Spring Boot Starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- MySQL驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.29</version>
</dependency>

<!-- MyBatis-Plus Starter -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3</version>
</dependency>

2. 配置 application.yml

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

mybatis-plus:
  mapper-locations: classpath:mapper/**/*.xml
  configuration:
    mapUnderscoreToCamelCase: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3. 编写实体类 User.java

import com.baomidou.mybatisplus.annotation.*;

@Data
@TableName("users")
public class User {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    private String name;

    private String email;

    @TableLogic
    private Integer deleted; // 逻辑删除字段

    @Version
    private Integer version; // 乐观锁字段
}

4. Mapper 接口 UserMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

public interface UserMapper extends BaseMapper<User> {
}

5. Service 层 UserService.java

import com.baomidou.mybatisplus.extension.service.IService;

public interface UserService extends IService<User> {
}
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

6. 控制器层 UserController.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping
    public List<User> getAllUsers() {
        return userService.list();
    }

    @PostMapping
    public boolean createUser(@RequestBody User user) {
        return userService.save(user);
    }
}

🛠️ 四、MyBatis-Plus 进阶功能详解

1. QueryWrapper 构建查询条件

List<User> users = userMapper.selectList(new QueryWrapper<User>()
    .eq("name", "Alice")
    .ge("age", 18));

2. LambdaQueryWrapper(更安全、更直观)

List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>()
    .like(User::getName, "Tom")
    .lt(User::getAge, 30));

3. 分页查询(配置分页插件)

启用分页插件:
@Configuration
@MapperScan("com.example.mapper")
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
使用分页:
Page<User> page = new Page<>(1, 10); // 第一页,每页10条
IPage<User> userPage = userService.page(page);
System.out.println("总页数:" + userPage.getPages());
System.out.println("当前页数据:" + userPage.getRecords());

4. 乐观锁更新(解决并发修改问题)

// 修改前先获取用户信息
User user = userService.getById(1L);
user.setName("NewName");
user.setVersion(user.getVersion() + 1);

// 更新时会自动判断 version 是否一致
userService.updateById(user);

5. 逻辑删除(替代物理删除)

只需在字段上加注解即可:

@TableLogic
private Integer deleted;

执行 removeById(id) 时会自动改为更新 deleted=1


💡 五、实战案例:用户管理系统(Spring Boot + MyBatis-Plus)

功能包括:

  • 用户增删改查
  • 分页列表展示
  • 模糊搜索姓名
  • 逻辑删除用户
  • 乐观锁更新用户信息

完整源码结构如下:

src/
├── main/
│   ├── java/
│   │   └── com.example.demo/
│   │       ├── controller/UserController.java
│   │       ├── service/UserService.java
│   │       ├── service/impl/UserServiceImpl.java
│   │       ├── mapper/UserMapper.java
│   │       └── entity/User.java
│   └── resources/
│       ├── application.yml
│       └── mapper/
└── test/

🚀 六、MyBatis-Plus 高级特性

✅ 代码生成器 AutoGenerator

  1. 自动生成

    • Entity(POJO 类)
    • Mapper(DAO 接口)
    • Mapper XML(SQL 映射文件)
    • Service & ServiceImpl(服务层)
    • Controller(Web 层)
  2. 支持特性

    • 自定义模板引擎(Velocity/Freemarker/Beetl)
    • 表前缀过滤、字段名转换
    • Lombok 支持
    • Swagger 注解集成
    • 覆盖已存在文件
使用步骤(Spring Boot 项目示例)
1. 添加依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.4</version> <!-- 使用最新版本 -->
</dependency>
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version> <!-- 模板引擎 -->
</dependency>
2. 编写生成器配置类
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

public class CodeGenerator {

    public static void main(String[] args) {
        // 1. 数据源配置
        DataSourceConfig dsc = new DataSourceConfig.Builder(
            "jdbc:mysql://localhost:3306/your_db",
            "root",
            "password"
        ).build();

        // 2. 全局配置
        GlobalConfig gc = new GlobalConfig.Builder()
            .outputDir(System.getProperty("user.dir") + "/src/main/java")
            .author("YourName")
            .openDir(false) // 生成后不打开目录
            .fileOverride() // 覆盖已生成文件
            .enableSwagger() // 开启 Swagger 注解
            .build();

        // 3. 包配置
        PackageConfig pc = new PackageConfig.Builder()
            .parent("com.example")
            .moduleName("system")
            .entity("entity")
            .mapper("mapper")
            .service("service")
            .controller("controller")
            .build();

        // 4. 策略配置(表级)
        StrategyConfig sc = new StrategyConfig.Builder()
            .addInclude("user", "role") // 指定生成表名
            .addTablePrefix("tbl_") // 过滤表前缀
            .entityBuilder()
                .naming(NamingStrategy.underline_to_camel) // 字段转驼峰
                .enableLombok() // 使用 Lombok
                .logicDeleteColumnName("deleted") // 逻辑删除字段
            .controllerBuilder()
                .enableRestStyle() // 生成 @RestController
            .build();

        // 5. 执行生成
        AutoGenerator generator = new AutoGenerator(dsc);
        generator.global(gc)
                 .packageInfo(pc)
                 .strategy(sc)
                 .execute();
    }
}

关键配置详解
配置项 作用
DataSourceConfig 配置数据库连接
GlobalConfig 设置输出路径、作者、是否覆盖文件、开启 Swagger 等
PackageConfig 定义包路径(entity/mapper/service 等子包名)
StrategyConfig 核心配置
- addInclude():指定生成表
- addTablePrefix():过滤表前缀
- naming():字段命名策略
- enableLombok():简化实体类
TemplateConfig 自定义模板(如需修改生成代码格式)

高级用法
1. 自定义模板
TemplateConfig tc = new TemplateConfig.Builder()
    .entity("/templates/entity.java.vm") // 指定自定义实体模板路径
    .controller(null) // 不生成 Controller
    .build();
generator.template(tc);
2. 字段类型映射
StrategyConfig sc = new StrategyConfig.Builder()
    .entityBuilder()
        .addTableFills(new Column("create_time", FieldFill.INSERT)) // 自动填充
        .idType(IdType.AUTO) // 主键策略
        .columnNaming(NamingStrategy.no_change) // 字段名保持原样
    .build();
3. 生成 Service 接口时跳过已存在的方法
sc.serviceBuilder()
   .formatServiceFileName("%sService") // 自定义 Service 接口名
   .superServiceClass(BaseService.class); // 自定义 Service 基类

生成结果示例
// Entity(Lombok 简化)
@Data
@TableName("tbl_user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

// Mapper 接口
public interface UserMapper extends BaseMapper<User> {}

// Service 接口
public interface UserService extends IService<User> {}

// Controller
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
}

最佳实践
  1. 增量生成
    首次生成后,后续只生成新表代码时,通过 addInclude("new_table") 指定新表,避免覆盖自定义代码。

  2. 模板定制
    复制默认模板(在 mybatis-plus-generator 源码中)到 resources/templates 修改,实现个性化代码风格。

  3. 集成到构建流程
    通过 Maven/Gradle 插件在编译时自动生成代码(需额外配置)。

✅ 多租户支持(适用于 SaaS 架构)

通过 TenantLineInnerInterceptor 实现租户隔离。


💬 七、常见面试题解析

Q1: MyBatis-Plus 和 MyBatis 的区别?

答:MyBatis-Plus 是 MyBatis 的增强工具,提供了通用 CRUD、条件构造器、自动分页等封装,减少了重复代码。

Q2: 如何实现分页查询?

答:引入分页插件并使用 Page<T> 对象,结合 selectPage() 方法即可。

Q3: QueryWrapper 和 LambdaQueryWrapper 的区别?

答:QueryWrapper 使用字符串拼接字段名,容易出错;LambdaQueryWrapper 使用方法引用,类型安全。

Q4: 什么是逻辑删除?如何启用?

答:逻辑删除是“假删除”,通过字段标记是否删除。只需在字段上添加 @TableLogic 注解即可。

Q5: 如何实现乐观锁?

答:使用 @Version 注解标注版本号字段,并在更新时自动进行版本校验。


💥 八、总结

通过本文的学习,你应该已经掌握了:

  • MyBatis-Plus 的基本原理与使用方式
  • 如何使用 QueryWrapper 和 LambdaQueryWrapper 构建复杂查询条件
  • 如何实现自动分页、逻辑删除、乐观锁等高级功能
  • 与 Spring Boot 的整合方法
  • 代码生成器的使用技巧
  • 常见面试题解析

MyBatis-Plus 是 Java 持久层开发中的强大助手,既能保持灵活性,又能大幅提升开发效率,是构建高性能后端系统的首选之一。


  • 如果你在学习过程中遇到任何疑问,欢迎在评论区留言交流!
  • 👍 如果你觉得这篇文章对你有帮助,别忘了点赞、收藏、转发哦!

网站公告

今日签到

点亮在社区的每一天
去签到