MyBatis-Plus:简化你的CRUD

目录

[一、MyBatis-Plus 简介](#一、MyBatis-Plus 简介)

[二、环境搭建:快速集成 MyBatis-Plus](#二、环境搭建:快速集成 MyBatis-Plus)

[2.1 依赖配置(Spring Boot 项目)](#2.1 依赖配置(Spring Boot 项目))

[2.2 配置文件(application.yml)](#2.2 配置文件(application.yml))

[2.3 启动类配置](#2.3 启动类配置)

[三、核心功能:CRUD 操作的 "自动化"](#三、核心功能:CRUD 操作的 “自动化”)

[3.1 实体类与表映射](#3.1 实体类与表映射)

[3.2 BaseMapper:数据访问层的 "原子操作"](#3.2 BaseMapper:数据访问层的 “原子操作”)

[3.2.1 定义 Mapper 接口](#3.2.1 定义 Mapper 接口)

[3.2.2 常用方法示例](#3.2.2 常用方法示例)

[3.3 IService 与 ServiceImpl:业务层的 "组合操作"](#3.3 IService 与 ServiceImpl:业务层的 “组合操作”)

[3.3.1 定义 Service 接口与实现类](#3.3.1 定义 Service 接口与实现类)

[3.3.2 IService 常用方法示例](#3.3.2 IService 常用方法示例)

四、条件构造器:灵活拼接查询条件

[4.1 QueryWrapper:基于字符串的条件构造](#4.1 QueryWrapper:基于字符串的条件构造)

[4.2 LambdaQueryWrapper:类型安全的条件构造](#4.2 LambdaQueryWrapper:类型安全的条件构造)

[4.3 常用条件方法](#4.3 常用条件方法)

五、高级特性:提升开发效率的实用功能

[5.1 分页插件](#5.1 分页插件)

[5.1.1 配置分页插件](#5.1.1 配置分页插件)

[5.1.2 使用分页查询](#5.1.2 使用分页查询)

[5.2 逻辑删除](#5.2 逻辑删除)

[5.2.1 实体类添加逻辑删除字段](#5.2.1 实体类添加逻辑删除字段)

[5.2.2 配置逻辑删除(可选)](#5.2.2 配置逻辑删除(可选))

[5.2.3 效果验证](#5.2.3 效果验证)

[5.3 字段自动填充](#5.3 字段自动填充)

[5.3.1 实体类标记填充字段](#5.3.1 实体类标记填充字段)

[5.3.2 实现填充处理器](#5.3.2 实现填充处理器)

[5.4 代码生成器](#5.4 代码生成器)

[5.4.1 添加代码生成器依赖](#5.4.1 添加代码生成器依赖)

[5.4.2 编写生成器配置类](#5.4.2 编写生成器配置类)

[六、MyBatis-Plus 与 MyBatis 的兼容:自定义 SQL](#六、MyBatis-Plus 与 MyBatis 的兼容:自定义 SQL)

[6.1 注解方式自定义 SQL](#6.1 注解方式自定义 SQL)

[6.2 XML 方式自定义 SQL](#6.2 XML 方式自定义 SQL)

七、总结


在 Java 持久层框架中,MyBatis 凭借其灵活的 SQL 控制能力占据了重要地位,但原生 MyBatis 需要手动编写大量 XML 或注解 SQL,开发效率较低。MyBatis-Plus(简称 MP)作为 MyBatis 的增强工具,在保留 MyBatis 所有功能的基础上,提供了一系列开箱即用的特性,彻底解决了 "重复 CRUD 代码" 的痛点。本文将从基础到进阶,全面解析 MyBatis-Plus 的核心知识点与实战技巧。

一、MyBatis-Plus 简介

MyBatis-Plus 是由 baomidou 团队开发的 MyBatis 增强工具,其设计理念是 "只做增强,不做改变"。这意味着它完全兼容 MyBatis 的原生功能,同时通过封装常用操作,让开发者无需编写 SQL 即可完成大部分 CRUD 工作,大幅提升开发效率。

核心优势

  • 自动生成 CRUD 方法,无需手写 SQL;
  • 强大的条件构造器,灵活拼接查询条件;
  • 内置分页插件、逻辑删除、字段自动填充等实用功能;
  • 支持代码生成器,一键生成实体类、Mapper、Service 等代码;
  • 与 Spring Boot 无缝集成,开箱即用。

二、环境搭建:快速集成 MyBatis-Plus

2.1 依赖配置(Spring Boot 项目)

pom.xml 中引入 MyBatis-Plus 核心依赖(需排除 MyBatis 原生依赖,避免冲突):

复制代码
<!-- MyBatis-Plus 核心依赖 -->
<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>

<!-- Lombok(简化实体类 getter/setter,可选但推荐) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

2.2 配置文件(application.yml)

配置数据库连接信息及 MyBatis-Plus 基础参数:

复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mp_demo?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

# MyBatis-Plus 配置
mybatis-plus:
  # 实体类包路径(可选,用于扫描实体类)
  type-aliases-package: com.example.mpdemo.entity
  # Mapper XML 文件路径(若使用 XML 编写 SQL)
  mapper-locations: classpath:mapper/*.xml
  configuration:
    # 日志打印 SQL(开发环境推荐开启)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    # 驼峰命名映射(如实体类属性 user_name 映射数据库字段 user_name)
    map-underscore-to-camel-case: true

2.3 启动类配置

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

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

@SpringBootApplication
@MapperScan("com.example.mpdemo.mapper") // Mapper 接口所在包
public class MpDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(MpDemoApplication.class, args);
    }
}

三、核心功能:CRUD 操作的 "自动化"

MyBatis-Plus 的核心优势在于通过 BaseMapperIService 接口,将常用 CRUD 操作封装为现成方法,开发者无需编写 SQL 即可直接调用。

3.1 实体类与表映射

首先定义实体类,通过注解与数据库表关联:

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

@Data // Lombok 注解,自动生成 getter/setter
@TableName("user") // 映射数据库表名(若类名与表名一致可省略)
public class User {
    // 主键策略:ASSIGN_ID 表示使用雪花算法生成唯一 ID(分布式环境推荐)
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    
    // 若属性名与表字段名一致,无需额外注解(默认驼峰转下划线,如 userName → user_name)
    private String userName; 
    
    private Integer age;
    
    private String email;
}

常用注解说明

  • @TableName:指定实体类对应的数据库表名;
  • @TableId:标记主键字段,type 可指定主键生成策略(如 AUTO 自增、ASSIGN_UUID UUID 等);
  • @TableField:指定非主键字段与表字段的映射关系(如 @TableField("nick_name") 表示属性对应表字段 nick_name)。

3.2 BaseMapper:数据访问层的 "原子操作"

BaseMapper 是 MyBatis-Plus 提供的基础 Mapper 接口,定义了 17 种常用数据库操作方法。开发者只需让自定义 Mapper 接口继承 BaseMapper,即可直接使用这些方法,无需编写 XML 或 SQL 注解。

3.2.1 定义 Mapper 接口
复制代码
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mpdemo.entity.User;

// 继承 BaseMapper<T>,泛型为实体类
public interface UserMapper extends BaseMapper<User> {
    // 无需编写方法,直接继承 BaseMapper 的所有 CRUD 方法
}
3.2.2 常用方法示例
复制代码
import com.example.mpdemo.entity.User;
import com.example.mpdemo.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;

@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

    // 新增
    @Test
    public void testInsert() {
        User user = new User();
        user.setUserName("张三");
        user.setAge(20);
        user.setEmail("zhangsan@example.com");
        int rows = userMapper.insert(user); // 返回影响行数
        System.out.println("新增成功,ID:" + user.getId()); // 插入后自动回填 ID
    }

    // 根据 ID 查询
    @Test
    public void testSelectById() {
        User user = userMapper.selectById(1L); // 传入主键 ID
        System.out.println(user);
    }

    // 查询所有
    @Test
    public void testSelectList() {
        List<User> userList = userMapper.selectList(null); // 参数为查询条件,null 表示查询所有
        userList.forEach(System.out::println);
    }

    // 根据 ID 更新
    @Test
    public void testUpdateById() {
        User user = new User();
        user.setId(1L);
        user.setAge(21); // 仅更新指定字段
        int rows = userMapper.updateById(user);
        System.out.println("更新成功,影响行数:" + rows);
    }

    // 根据 ID 删除
    @Test
    public void testDeleteById() {
        int rows = userMapper.deleteById(1L);
        System.out.println("删除成功,影响行数:" + rows);
    }
}

3.3 IService 与 ServiceImpl:业务层的 "组合操作"

IService 是业务逻辑层的基础接口,封装了 BaseMapper 的基础操作,并提供了更丰富的业务级方法(如批量操作、分页查询等)。其实现类 ServiceImpl<M, T> 需指定对应的 Mapper 接口和实体类,简化 Service 层代码编写。

3.3.1 定义 Service 接口与实现类
复制代码
// Service 接口(继承 IService<T>)
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mpdemo.entity.User;

public interface UserService extends IService<User> {
    // 可自定义业务方法
}

// Service 实现类(继承 ServiceImpl<M, T>,实现自定义 Service 接口)
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.mapper.UserMapper;
import com.example.mpdemo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    // 继承 ServiceImpl 后,可直接使用 baseMapper 调用 Mapper 方法,或使用 IService 的默认方法
}
3.3.2 IService 常用方法示例
复制代码
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.List;

@SpringBootTest
public class UserServiceTest {
    @Autowired
    private UserService userService;

    // 批量新增
    @Test
    public void testSaveBatch() {
        User user1 = new User();
        user1.setUserName("李四");
        user1.setAge(22);
        
        User user2 = new User();
        user2.setUserName("王五");
        user2.setAge(23);
        
        // 批量保存,默认批次大小为 1000,可指定第二个参数调整
        boolean success = userService.saveBatch(Arrays.asList(user1, user2));
        System.out.println("批量新增成功:" + success);
    }

    // 分页查询
    @Test
    public void testPage() {
        // 第 1 页,每页 2 条数据
        Page<User> page = new Page<>(1, 2);
        // 执行分页查询(第二个参数为查询条件,null 表示无额外条件)
        IPage<User> userPage = userService.page(page, null);
        
        System.out.println("总条数:" + userPage.getTotal());
        System.out.println("总页数:" + userPage.getPages());
        System.out.println("当前页数据:" + userPage.getRecords());
    }

    // 批量删除
    @Test
    public void testRemoveByIds() {
        boolean success = userService.removeByIds(Arrays.asList(1L, 2L)); // 传入 ID 列表
        System.out.println("批量删除成功:" + success);
    }
}

四、条件构造器:灵活拼接查询条件

在实际开发中,查询条件往往复杂(如多字段筛选、模糊查询、排序等)。MyBatis-Plus 提供的 QueryWrapperLambdaQueryWrapper 可以通过链式调用快速构建条件,替代手动拼接 SQL 的过程,且避免 SQL 注入风险。

4.1 QueryWrapper:基于字符串的条件构造

复制代码
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;

@SpringBootTest
public class QueryWrapperTest {
    @Autowired
    private UserService userService;

    @Test
    public void testQuery() {
        // 构建查询条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 年龄 > 18 且邮箱不为空
        queryWrapper.gt("age", 18).isNotNull("email");
        // 用户名包含 "张"(模糊查询)
        queryWrapper.like("user_name", "张");
        // 按年龄降序排序
        queryWrapper.orderByDesc("age");
        
        // 执行查询
        List<User> userList = userService.list(queryWrapper);
        userList.forEach(System.out::println);
    }
}

4.2 LambdaQueryWrapper:类型安全的条件构造

LambdaQueryWrapper 通过 Lambda 表达式引用实体类的 getter 方法,避免手动输入字段名(减少拼写错误),且编译时会校验字段合法性,更推荐使用。

复制代码
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;

@SpringBootTest
public class LambdaQueryWrapperTest {
    @Autowired
    private UserService userService;

    @Test
    public void testLambdaQuery() {
        // 构建 Lambda 条件构造器(泛型为实体类)
        LambdaQueryWrapper<User> lambdaQuery = new LambdaQueryWrapper<>();
        // 年龄 >= 20 且 <= 30
        lambdaQuery.ge(User::getAge, 20).le(User::getAge, 30);
        // 邮箱以 "@example.com" 结尾
        lambdaQuery.likeRight(User::getEmail, "@example.com");
        // 按用户名升序排序
        lambdaQuery.orderByAsc(User::getUserName);
        
        List<User> userList = userService.list(lambdaQuery);
        userList.forEach(System.out::println);
    }
}

4.3 常用条件方法

方法 说明 示例
eq 等于(=) eq("age", 20)eq(User::getAge, 20)
ne 不等于(≠) ne("email", null)
gt/ge 大于(>)/ 大于等于(≥) gt("age", 18)
lt/le 小于(<)/ 小于等于(≤) le("age", 30)
like 模糊查询(% 值 %) like("user_name", "张")
likeLeft/likeRight 左模糊(% 值)/ 右模糊(值 %) likeRight("email", "@qq.com")
in 包含(IN) in("id", 1, 2, 3)
orderByAsc/orderByDesc 升序 / 降序排序 orderByAsc("age")
and/or 拼接 AND/OR 条件(嵌套复杂条件时使用) and(wrapper -> wrapper.gt("age", 18).lt("age", 30))

五、高级特性:提升开发效率的实用功能

5.1 分页插件

MyBatis-Plus 内置分页插件,无需手动编写 LIMIT 语句,配置后即可使用分页功能。

5.1.1 配置分页插件
复制代码
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(com.baomidou.mybatisplus.annotation.DbType.MYSQL));
        return interceptor;
    }
}
5.1.2 使用分页查询
复制代码
// 分页查询年龄 > 18 的用户,第 2 页,每页 10 条
Page<User> page = new Page<>(2, 10);
LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
query.gt(User::getAge, 18);

IPage<User> result = userService.page(page, query);
System.out.println("总条数:" + result.getTotal());
System.out.println("当前页数据:" + result.getRecords());

5.2 逻辑删除

逻辑删除是指通过字段标记数据 "删除状态"(如 deleted=1 表示已删除),而非物理删除(从数据库中删除记录)。MyBatis-Plus 可通过注解自动实现逻辑删除的 SQL 拼接。

5.2.1 实体类添加逻辑删除字段
复制代码
import com.baomidou.mybatisplus.annotation.TableLogic;

public class User {
    // 其他字段...
    
    // 逻辑删除字段:0=未删除,1=已删除(默认值为 0)
    @TableLogic
    private Integer deleted;
}
5.2.2 配置逻辑删除(可选)

若默认的 "未删除值"(0)和 "已删除值"(1)不符合需求,可在 application.yml 中自定义:

复制代码
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted # 全局逻辑删除字段名(可选)
      logic-not-delete-value: 0 # 未删除值
      logic-delete-value: 1 # 已删除值
5.2.3 效果验证

调用 deleteById 时,实际执行的是更新操作:

复制代码
// 调用删除方法
userService.removeById(1L);

// 生成的 SQL:UPDATE user SET deleted=1 WHERE id=1 AND deleted=0

查询时,会自动拼接 deleted=0 条件:

复制代码
// 调用查询方法
userService.list();

// 生成的 SQL:SELECT * FROM user WHERE deleted=0

5.3 字段自动填充

对于创建时间、更新时间等字段,可通过 MyBatis-Plus 的自动填充功能,在新增或更新时自动赋值,无需手动设置。

5.3.1 实体类标记填充字段
复制代码
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import java.time.LocalDateTime;

public class User {
    // 其他字段...
    
    // 新增时自动填充
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    // 新增和更新时自动填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
5.3.2 实现填充处理器
复制代码
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;

@Component // 注入 Spring 容器
public class MyMetaObjectHandler implements MetaObjectHandler {
    // 新增时填充
    @Override
    public void insertFill(MetaObject metaObject) {
        // 填充 createTime 和 updateTime 为当前时间
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }

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

5.4 代码生成器

MyBatis-Plus 提供的 AutoGenerator 可以一键生成实体类、Mapper 接口、Service、Controller 等代码,支持自定义模板,极大减少重复劳动。

5.4.1 添加代码生成器依赖
复制代码
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.3.1</version>
</dependency>

<!-- 模板引擎(默认使用 Velocity) -->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>
5.4.2 编写生成器配置类
复制代码
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import java.util.Collections;

public class CodeGenerator {
    public static void main(String[] args) {
        // 数据库连接配置
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp_demo", "root", "123456")
                // 全局配置
                .globalConfig(builder -> {
                    builder.author("开发者") // 设置作者
                            .outputDir(System.getProperty("user.dir") + "/src/main/java") // 输出路径(项目的 java 目录)
                            .disableOpenDir(); // 生成后不打开文件夹
                })
                // 包配置
                .packageConfig(builder -> {
                    builder.parent("com.example.mpdemo") // 父包名
                            .moduleName("") // 模块名(无子模块可留空)
                            .mapper("mapper") // Mapper 包名
                            .service("service") // Service 包名
                            .controller("controller") // Controller 包名
                            .entity("entity") // 实体类包名
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, 
                                    System.getProperty("user.dir") + "/src/main/resources/mapper")); // Mapper XML 路径
                })
                // 策略配置
                .strategyConfig(builder -> {
                    builder.addInclude("user") // 需要生成的表名(可多个)
                            .entityBuilder() // 实体类策略
                            .enableLombok() // 启用 Lombok
                            .enableTableFieldAnnotation() // 生成字段注解
                            .mapperBuilder() // Mapper 策略
                            .enableBaseResultMap() // 生成 BaseResultMap
                            .serviceBuilder() // Service 策略
                            .formatServiceFileName("%sService") // Service 接口名格式
                            .controllerBuilder() // Controller 策略
                            .enableRestStyle(); // 启用 REST 风格
                })
                .execute(); // 执行生成
    }
}

运行上述代码后,会在指定目录自动生成全套代码,直接投入使用。

六、MyBatis-Plus 与 MyBatis 的兼容:自定义 SQL

MyBatis-Plus 完全兼容 MyBatis,对于复杂查询(如多表关联),可通过 XML 或注解编写自定义 SQL。

6.1 注解方式自定义 SQL

复制代码
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.example.mpdemo.entity.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;

public interface UserMapper extends BaseMapper<User> {
    // 自定义查询:查询年龄大于指定值的用户
    @Select("SELECT * FROM user WHERE age > #{age} ${ew.customSqlSegment}")
    List<User> selectByAgeGreaterThan(Integer age, @Param(Constants.WRAPPER) Wrapper<User> wrapper);
}

6.2 XML 方式自定义 SQL

resources/mapper 目录下创建 UserMapper.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.mpdemo.mapper.UserMapper">
    <!-- 自定义分页查询:多表关联查询(示例) -->
    <select id="selectUserWithRole" resultType="com.example.mpdemo.vo.UserRoleVO">
        SELECT u.id, u.user_name, r.role_name 
        FROM user u
        LEFT JOIN user_role ur ON u.id = ur.user_id
        LEFT JOIN role r ON ur.role_id = r.id
        ${ew.customSqlSegment}
    </select>
</mapper>

在 Mapper 接口中定义方法:

复制代码
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.vo.UserRoleVO;
import org.apache.ibatis.annotations.Param;

public interface UserMapper extends BaseMapper<User> {
    IPage<UserRoleVO> selectUserWithRole(Page<UserRoleVO> page, @Param(Constants.WRAPPER) Wrapper<User> wrapper);
}

七、总结

MyBatis-Plus 作为 MyBatis 的增强工具,通过自动化 CRUD、条件构造器、分页插件等特性,极大简化了持久层开发。其核心价值在于:

  • 减少重复劳动:自动生成 CRUD 代码,避免手写 SQL;
  • 提升开发效率:代码生成器、字段自动填充等功能节省大量时间;
  • 增强安全性:参数绑定避免 SQL 注入,Lambda 条件构造器减少字段拼写错误;
  • 灵活兼容:完全兼容 MyBatis,支持自定义 SQL 应对复杂场景。

无论是小型项目还是大型企业级应用,MyBatis-Plus 都能显著提升开发效率,是 Java 开发者值得掌握的实用工具。

官方文档:https://baomidou.com/guide/(最新特性和详细配置可参考官方文档)

相关推荐
自由鬼1 小时前
如何处理Y2K38问题
java·运维·服务器·程序人生·安全·操作系统
_oP_i4 小时前
RabbitMQ 队列配置设置 RabbitMQ 消息监听器的并发消费者数量java
java·rabbitmq·java-rabbitmq
Monkey-旭4 小时前
Android Bitmap 完全指南:从基础到高级优化
android·java·人工智能·计算机视觉·kotlin·位图·bitmap
我爱996!4 小时前
SpringMVC——响应
java·服务器·前端
小宋10215 小时前
多线程向设备发送数据
java·spring·多线程
大佐不会说日语~6 小时前
Redis高频问题全解析
java·数据库·redis
寒水馨6 小时前
Java 17 新特性解析与代码示例
java·开发语言·jdk17·新特性·java17
启山智软6 小时前
选用Java开发商城的优势
java·开发语言
鹦鹉0076 小时前
SpringMVC的基本使用
java·spring·html·jsp
R cddddd6 小时前
Maven模块化开发与设计笔记
java·maven