MyBatis-Plus实战指南:从CRUD简化到企业级进阶

27 阅读14分钟

MyBatis-Plus实战指南:从CRUD简化到企业级进阶

在Java持久层开发中,MyBatis凭借灵活的SQL控制能力成为主流选择,但原生MyBatis存在大量重复CRUD代码、分页逻辑冗余、条件查询繁琐等问题。MyBatis-Plus(简称MP)作为MyBatis的增强工具,在完全兼容MyBatis的基础上,提供了无侵入式的增强功能,大幅简化开发流程。本文从核心特性、实战落地、进阶功能到生产避坑,完整拆解MyBatis-Plus的使用全流程,助力开发者提升持久层开发效率。

一、为什么选择MyBatis-Plus?核心价值解析

原生MyBatis在实际开发中面临诸多痛点:单表CRUD需手动编写XML映射文件、分页查询需自定义拦截器、条件查询拼接SQL易出错且冗余。MyBatis-Plus的核心价值在于“增强不改变”,既保留MyBatis的灵活性,又通过自动化能力解决重复劳动,具体优势如下:

  • 零XML单表CRUD:内置BaseMapper接口,提供全量单表操作方法,无需编写SQL即可完成增删改查;
  • 灵活条件构造:通过Lambda条件构造器,支持类型安全的条件查询,避免SQL拼接错误;
  • 自动化分页:内置分页插件,一行配置即可实现物理分页,无需手动处理分页逻辑;
  • 多场景增强功能:支持乐观锁、逻辑删除、代码生成器、多数据源等企业级功能,开箱即用;
  • 无缝兼容生态:与Spring Boot、Sharding-JDBC、Seata等框架完美集成,适配微服务架构。

选型建议:若项目已使用MyBatis,可无缝集成MyBatis-Plus;新项目优先选择MyBatis-Plus,能减少50%以上的持久层代码量。

二、MyBatis-Plus核心特性:从基础到增强

1. 核心架构与设计理念

MyBatis-Plus基于MyBatis的插件机制实现增强,核心架构分为三层,对原生MyBatis无侵入:

  • API层:提供BaseMapper、Service层接口,封装单表CRUD、批量操作等方法;
  • 核心层:包含条件构造器、分页插件、乐观锁插件、逻辑删除插件等核心增强组件;
  • 适配层:兼容MyBatis的XML映射、注解SQL,支持Spring Boot、Spring MVC等主流框架集成。

设计理念:约定大于配置,通过默认规则自动适配数据库表结构与实体类,减少配置成本;同时支持自定义扩展,兼顾规范性与灵活性。

2. 核心功能速览

功能模块核心能力使用场景
BaseMapper接口内置insert、delete、update、select系列方法,覆盖单表全量CRUD大部分单表操作场景,无需编写SQL
Lambda条件构造器基于Lambda表达式构建查询条件,类型安全,避免字段名硬编码复杂条件查询、动态SQL场景
分页插件自动拦截分页查询,生成物理分页SQL,支持多种数据库列表分页、分页筛选场景
乐观锁插件通过版本号机制防止并发更新冲突,自动拼接版本号条件库存扣减、订单状态更新等并发场景
逻辑删除假删除机制,更新删除标记字段,不物理删除数据需要数据回溯、避免误删的业务场景
代码生成器根据数据库表结构,自动生成实体类、Mapper、Service、Controller项目初始化、新增表结构时快速生成代码
多数据源支持动态切换多数据源,适配读写分离、多库关联场景跨库查询、主从架构场景

三、实战:MyBatis-Plus集成Spring Boot(基础篇)

以电商订单模块为例,实现MyBatis-Plus的基础集成与单表CRUD操作。技术栈:Spring Boot 2.7.x + MyBatis-Plus 3.5.3.1 + MySQL 8.0 + Druid连接池。

1. 环境准备

(1)引入核心依赖

pom.xml中引入MyBatis-Plus Starter、MySQL驱动、Druid连接池依赖,无需额外引入MyBatis(Starter已包含):

<!-- Spring Boot Web核心 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

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

<!-- MySQL驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

<!-- Druid连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.16</version>
</dependency>

<!-- Lombok(简化实体类) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
(2)核心配置

application.yml中配置数据源、MyBatis-Plus基础参数,无需额外配置MyBatis核心文件:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/order_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username: root
    password: 123456
    # Druid连接池配置
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      max-wait: 60000

# MyBatis-Plus配置
mybatis-plus:
  #  mapper.xml文件路径
  mapper-locations: classpath:mapper/**/*.xml
  # 实体类扫描路径
  type-aliases-package: com.example.mp.entity
  configuration:
    # 驼峰命名自动映射
    map-underscore-to-camel-case: true
    # 日志打印SQL(开发环境开启,生产环境关闭)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  # 全局配置
  global-config:
    db-config:
      # 主键生成策略(雪花算法)
      id-type: ASSIGN_ID
      # 逻辑删除字段名
      logic-delete-field: deleted
      # 逻辑删除值(1=删除)
      logic-delete-value: 1
      # 逻辑未删除值(0=正常)
      logic-not-delete-value: 0
(3)启动类配置

启动类上添加@MapperScan注解,扫描Mapper接口所在包:

package com.example.mp;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
// 扫描Mapper接口包
@MapperScan("com.example.mp.mapper")
public class MyBatisPlusDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyBatisPlusDemoApplication.class, args);
    }
}

2. 基础CRUD实现(零XML)

(1)实体类定义

使用Lombok简化实体类,通过注解映射数据库表与字段:

package com.example.mp.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;

@Data
// 映射数据库表名(表名与类名一致可省略)
@TableName("t_order")
public class Order {
    // 主键,使用雪花算法生成
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    
    // 订单编号(与表字段一致可省略@TableField)
    private String orderNo;
    
    // 用户ID
    private Long userId;
    
    // 订单金额
    private BigDecimal amount;
    
    // 订单状态(0-待支付,1-已支付,2-已取消)
    private Integer status;
    
    // 创建时间(自动填充)
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    // 更新时间(自动填充)
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    
    // 逻辑删除字段(全局配置后可省略注解)
    @TableLogic
    private Integer deleted;
}
(2)Mapper接口定义

继承BaseMapper接口,无需编写方法即可获得全量单表CRUD能力:

package com.example.mp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mp.entity.Order;
import org.apache.ibatis.annotations.Mapper;

// @Mapper注解可在启动类通过@MapperScan批量扫描,此处可省略
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
    // 无需编写任何方法,BaseMapper已提供以下功能:
    // insert、deleteById、updateById、selectById、selectList、selectPage等
}
(3)Service层封装(可选)

继承IService接口与ServiceImpl实现类,获得更丰富的业务层方法(如批量操作、条件查询):

// Service接口
package com.example.mp.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mp.entity.Order;

public interface OrderService extends IService<Order> {
    // 可自定义业务方法,基础CRUD无需编写
}

// Service实现类
package com.example.mp.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mp.entity.Order;
import com.example.mp.mapper.OrderMapper;
import com.example.mp.service.OrderService;
import org.springframework.stereotype.Service;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    // 继承ServiceImpl后,自动获得IService的所有方法
}
(4)基础CRUD使用示例

Controller层调用Service/Mapper,实现无SQL的CRUD操作:

package com.example.mp.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.mp.entity.Order;
import com.example.mp.service.OrderService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Resource
    private OrderService orderService;

    // 新增订单
    @PostMapping("/add")
    public boolean addOrder() {
        Order order = new Order();
        order.setOrderNo("ORDER20260119001");
        order.setUserId(1001L);
        order.setAmount(new BigDecimal("199.00"));
        order.setStatus(0);
        return orderService.save(order);
    }

    // 根据ID查询订单
    @GetMapping("/{id}")
    public Order getOrderById(@PathVariable Long id) {
        return orderService.getById(id);
    }

    // 根据用户ID查询订单列表
    @GetMapping("/list/{userId}")
    public List<Order> getOrderList(@PathVariable Long userId) {
        // 条件构造器:查询用户ID=userId且未删除的订单
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId)
               .eq("deleted", 0);
        return orderService.list(wrapper);
    }

    // 更新订单状态
    @PutMapping("/update/status/{id}/{status}")
    public boolean updateOrderStatus(@PathVariable Long id, @PathVariable Integer status) {
        Order order = new Order();
        order.setId(id);
        order.setStatus(status);
        return orderService.updateById(order);
    }

    // 逻辑删除订单
    @DeleteMapping("/{id}")
    public boolean deleteOrder(@PathVariable Long id) {
        // 自动更新deleted字段为1,而非物理删除
        return orderService.removeById(id);
    }
}

3. 条件构造器进阶(Lambda方式)

使用LambdaQueryWrapper替代QueryWrapper,避免字段名硬编码,支持类型安全校验:

// 根据用户ID和订单状态查询,支持链式调用
LambdaQueryWrapper<Order> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.eq(Order::getUserId, 1001L)
             .eq(Order::getStatus, 1)
             .ge(Order::getCreateTime, LocalDateTime.of(2026, 1, 1, 0, 0))
             .orderByDesc(Order::getCreateTime);
List<Order> orderList = orderService.list(lambdaWrapper);

// 动态条件查询(避免if-else判断)
lambdaWrapper.eq(Order::getUserId, 1001L)
             .when(status != null, wrapper -> wrapper.eq(Order::getStatus, status))
             .like(StringUtils.hasText(orderNo), Order::getOrderNo, orderNo);

4. 分页功能实现

MyBatis-Plus内置分页插件,配置后即可实现物理分页,无需手动编写分页SQL:

(1)分页插件配置
package com.example.mp.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatisPlusConfig {

    // 配置分页插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加MySQL分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
(2)分页查询使用
// 分页查询用户订单(第1页,每页10条)
@GetMapping("/page/{userId}")
public IPage<Order> getOrderPage(@PathVariable Long userId, 
                                 @RequestParam(defaultValue = "1") Integer pageNum,
                                 @RequestParam(defaultValue = "10") Integer pageSize) {
    // 构建分页对象
    Page&lt;Order&gt; page = new Page<>(pageNum, pageSize);
    // 条件构造器
    LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Order::getUserId, userId)
           .eq(Order::getDeleted, 0);
    // 分页查询(自动生成物理分页SQL)
    return orderService.page(page, wrapper);
}

四、进阶功能:企业级场景实战

1. 自动填充功能

针对创建时间、更新时间等公共字段,通过自动填充功能避免重复赋值:

package com.example.mp.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    // 新增时自动填充
    @Override
    public void insertFill(MetaObject metaObject) {
        // 填充创建时间
        strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        // 填充更新时间
        strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }

    // 更新时自动填充
    @Override
    public void updateFill(MetaObject metaObject) {
        // 填充更新时间
        strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }
}

2. 乐观锁实现

解决并发更新冲突,通过版本号机制确保数据一致性:

(1)乐观锁插件配置
@Configuration
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}
(2)实体类添加版本字段
@Data
@TableName("t_order")
public class Order {
    // 其他字段省略...
    
    // 乐观锁版本号字段
    @Version
    private Integer version;
}
(3)使用示例
// 并发更新订单状态
public boolean updateOrderStatusWithLock(Long id, Integer status) {
    Order order = orderService.getById(id);
    order.setStatus(status);
    // 自动拼接条件:where id = ? and version = ?,更新成功后version+1
    return orderService.updateById(order);
}

3. 代码生成器(AutoGenerator)

基于数据库表结构自动生成实体类、Mapper、Service、Controller,大幅提升初始化效率:

package com.example.mp.generator;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.Collections;

public class CodeGenerator {
    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/order_db?useSSL=false&serverTimezone=Asia/Shanghai",
                        "root", "123456")
                // 全局配置
                .globalConfig(builder -> {
                    builder.author("开发者") // 作者
                            .outputDir(System.getProperty("user.dir") + "/src/main/java") // 输出路径
                            .disableOpenDir() // 禁止自动打开目录
                            .commentDate("yyyy-MM-dd HH:mm:ss"); // 注释日期
                })
                // 包配置
                .packageConfig(builder -> {
                    builder.parent("com.example.mp") // 父包名
                            .moduleName("order") // 模块名
                            .mapper("mapper") // Mapper包名
                            .service("service") // Service包名
                            .controller("controller") // Controller包名
                            .entity("entity") // 实体类包名
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, 
                                    System.getProperty("user.dir") + "/src/main/resources/mapper/order")); // MapperXML路径
                })
                // 策略配置
                .strategyConfig(builder -> {
                    builder.addInclude("t_order") // 生成的表名(多个表用逗号分隔)
                            .addTablePrefix("t_") // 表前缀(生成实体类时去掉前缀)
                            .entityBuilder()
                            .enableLombok() // 启用Lombok
                            .enableTableFieldAnnotation() // 启用字段注解
                            .controllerBuilder()
                            .enableRestStyle() // 启用RestController风格
                            .serviceBuilder()
                            .formatServiceFileName("%sService") // Service命名规则
                            .formatServiceImplFileName("%sServiceImpl");
                })
                // 模板引擎(Freemarker)
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
    }
}

4. 多数据源支持

通过MyBatis-Plus多数据源组件,实现读写分离、多库关联场景:

(1)引入多数据源依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.6.1</version>
</dependency>
(2)多数据源配置
spring:
  datasource:
    dynamic:
      primary: master # 主数据源
      strict: false # 非严格模式,允许未匹配数据源
      datasource:
        # 主数据源(写库)
        master:
          type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/order_db?useSSL=false&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
        # 从数据源(读库)
        slave:
          type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3307/order_db?useSSL=false&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
(3)使用示例(注解切换数据源)
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    // 写操作(默认主数据源)
    @Override
    public boolean saveOrder(Order order) {
        return save(order);
    }

    // 读操作(切换到从数据源)
    @Override
    @DS("slave")
    public List<Order> getOrderListByUserId(Long userId) {
        return lambdaQuery().eq(Order::getUserId, userId).list();
    }
}

5. 自定义SQL与MyBatis兼容

MyBatis-Plus完全兼容原生MyBatis,复杂查询可通过XML编写自定义SQL:

(1)Mapper接口定义方法
public interface OrderMapper extends BaseMapper<Order> {
    // 自定义SQL查询:关联用户表查询订单详情
    List<OrderVO> selectOrderVOList(@Param("userId") Long userId);
}
(2)XML编写自定义SQL
<?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.mp.mapper.OrderMapper">
    <select id="selectOrderVOList" resultType="com.example.mp.vo.OrderVO">
        SELECT o.id, o.order_no, o.amount, o.status, u.username
        FROM t_order o
        LEFT JOIN t_user u ON o.user_id = u.id
        WHERE o.user_id = #{userId} AND o.deleted = 0
    </select>
</mapper>

五、避坑指南:10个高频问题与解决方案

1. 坑点1:分页查询返回总条数为0

现象:分页查询时list有数据,但total为0,分页控件显示异常。 规避方案:

  • 确认已配置分页插件,且插件顺序正确(分页插件需添加到MybatisPlusInterceptor);
  • 避免使用逻辑删除时,手动拼接deleted条件与分页插件冲突,优先使用@TableLogic注解;
  • 检查数据库方言是否正确(如MySQL、Oracle需对应配置DbType)。

2. 坑点2:乐观锁不起作用

现象:并发更新时无版本号校验,数据被覆盖。 规避方案:

  • 确认已配置乐观锁插件,且插件已添加到MybatisPlusInterceptor;
  • 实体类版本字段需添加@Version注解,且字段类型为Integer/Long;
  • 更新操作必须通过updateById、update方法,且实体类中包含版本字段值。

3. 坑点3:逻辑删除后查询仍返回已删除数据

现象:调用removeById后,查询仍能获取到数据。 规避方案:

  • 确认全局配置了逻辑删除字段名、删除/未删除值;
  • 自定义SQL需手动添加deleted条件(MyBatis-Plus仅对BaseMapper方法自动拼接);
  • 检查实体类@TableLogic注解是否与全局配置冲突,二者选其一即可。

4. 坑点4:自动填充字段为null

现象:createTime、updateTime未自动填充,数据库字段为null。 规避方案:

  • 确认MetaObjectHandler实现类已添加@Component注解,被Spring扫描;
  • 实体类字段需添加@TableField(fill = FieldFill.INSERT/INSERT_UPDATE)注解;
  • 填充方法中字段名需与实体类一致,避免驼峰命名错误。

5. 坑点5:Lambda条件构造器字段名错误

现象:Lambda表达式引用实体类方法时,报字段不存在错误。 规避方案:

  • 确保实体类字段与数据库字段映射正确(驼峰与下划线自动映射需开启map-underscore-to-camel-case);
  • 避免Lambda表达式中引用非数据库映射字段(如transient修饰的临时字段);
  • 若字段名与关键字冲突,需通过@TableField注解指定数据库字段名(如@TableField("order"))。

6. 坑点6:多数据源切换失效

现象:@DS注解切换数据源无效果,始终使用主数据源。 规避方案:

  • 确认引入的是dynamic-datasource-spring-boot-starter依赖,而非原生多数据源依赖;
  • @DS注解可用于类或方法,方法注解优先级高于类注解;
  • 避免在事务中切换数据源,事务内数据源保持一致,需切换数据源可拆分事务。

7. 坑点7:代码生成器无法生成XML文件

现象:生成实体类、Mapper后,无MapperXML文件。 规避方案:

  • 确认配置了pathInfo,指定MapperXML的输出路径,且路径存在;
  • 检查模板引擎依赖是否引入(如Freemarker、Velocity);
  • 生成策略中启用XML生成(默认启用,若自定义策略需确保未禁用)。

8. 坑点8:与Sharding-JDBC集成冲突

现象:集成Sharding-JDBC后,分页、乐观锁插件失效。 规避方案:

  • 调整插件顺序,Sharding-JDBC插件需在MyBatis-Plus插件之前配置;
  • 分页查询需包含分表键,避免跨表分页导致MyBatis-Plus分页插件失效;
  • 禁用Sharding-JDBC的自带分页,统一使用MyBatis-Plus分页插件。

9. 坑点9:批量插入性能差

现象:使用saveBatch方法批量插入时,速度缓慢。 规避方案:

  • 配置JDBC批量提交参数:spring.datasource.druid.batch-open-result-set=true;
  • 分批次批量插入,每批次数量控制在500-1000条,避免单次插入过多数据;
  • 复杂场景可使用MyBatis原生批量插入XML,性能优于saveBatch。

10. 坑点10:事务中更新操作不生效

现象:在@Transactional事务中调用updateById,数据未更新且无报错。 规避方案:

  • 检查事务传播机制是否正确,避免事务未生效(如Propagation.NOT_SUPPORTED);
  • 确认更新的实体类包含主键ID,且ID对应的数据存在;
  • 避免在事务中同时调用多个更新方法,导致乐观锁冲突,可添加重试机制。

六、总结:MyBatis-Plus落地核心原则

MyBatis-Plus的核心价值在于“简化开发、兼顾灵活”,落地时需遵循以下原则,最大化发挥其优势:

  • 优先使用内置能力:单表操作、分页、条件查询优先使用BaseMapper、Lambda构造器,减少自定义SQL;
  • 约定大于配置:遵循MyBatis-Plus的命名规范、字段映射规则,减少冗余配置;
  • 灵活扩展不滥用:复杂查询可结合原生XML,多数据源、分布式事务场景按需集成,不过度依赖增强功能;
  • 适配微服务生态:与Spring Boot、Sharding-JDBC、Seata等组件协同使用时,注意插件顺序、数据源适配,确保整体稳定性。

MyBatis-Plus并非替代MyBatis,而是通过自动化能力解放开发者的重复劳动,让精力聚焦于复杂业务逻辑。掌握本文所述的基础用法、进阶功能与避坑要点,能大幅提升持久层开发效率,适配从单体应用到微服务的全场景需求。