MyBatis-Plus(简称 MP)是 MyBatis 的增强工具,核心理念是只做增强,不做改变,它在 MyBatis 基础上简化了大量重复的 CRUD 操作,无需编写繁琐的 XML 映射文件或注解 SQL,极大提升开发效率。下面从环境搭建核心功能常用特性三个维度,为你详细讲解 MP 的使用方法(以 Spring Boot + MySQL 为例)。

一、环境搭建

1. 引入依赖(Maven)

pom.xml 中添加核心依赖(Spring Boot 版本以 2.x/3.x 适配为准):

<!-- Spring Boot 基础依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- MyBatis-Plus 整合 Spring Boot -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.5</version> <!-- 推荐使用稳定版 -->
</dependency>

<!-- MySQL 驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<!-- 数据源(Spring Boot 内置 HikariCP) -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
</dependency>

<!-- Lombok(可选,简化实体类编写) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
2. 配置文件(application.yml)

配置数据源和 MP 基础属性:

spring:
  # 数据源配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mp_demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 你的数据库密码

# MyBatis-Plus 配置
mybatis-plus:
  # 实体类别名包扫描
  type-aliases-package: com.example.mpdemo.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  # 雪花算法生成主键(默认)
3. 核心组件准备
(1)实体类(Entity)

对应数据库表,使用 MP 注解映射字段关系(Lombok 简化代码):

package com.example.mpdemo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.time.LocalDateTime;

/**
 * 用户实体类,对应数据库表 user
 */
@Data  // Lombok 自动生成 getter/setter/toString 等
@TableName("user")  // 指定数据库表名(若类名与表名一致可省略)
public class User {
    // 主键,指定生成策略为雪花算法
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    
    // 用户名(字段名与属性名一致,无需额外注解)
    private String username;
    
    // 年龄
    private Integer age;
    
    // 邮箱(若数据库字段是 email,属性名也是 email,驼峰自动转换)
    private String email;
    
    // 创建时间(数据库字段 create_time,驼峰转换为 createTime)
    private LocalDateTime createTime;
}
(2)Mapper 接口

继承 MP 提供的 BaseMapper<T>,无需编写任何方法即可获得基础 CRUD 能力:

package com.example.mpdemo.mapper;

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

/**
 * 用户 Mapper 接口,继承 BaseMapper 获得基础 CRUD
 */
@Mapper  // 标记为 MyBatis Mapper 组件
public interface UserMapper extends BaseMapper<User> {
    // 无需编写任何方法,BaseMapper 已封装所有基础 CRUD
}
(3)启动类

添加 @MapperScan 扫描 Mapper 接口包:

package com.example.mpdemo;

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);
    }
}

二、核心功能使用

1. 基础 CRUD 操作

BaseMapper<T> 封装了 17 个基础 CRUD 方法,直接注入 Mapper 即可使用,示例如下(以测试类为例):

package com.example.mpdemo;

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.time.LocalDateTime;
import java.util.List;

@SpringBootTest
public class MpCrudTest {

    @Autowired
    private UserMapper userMapper;

    // 1. 新增
    @Test
    public void testInsert() {
        User user = new User();
        user.setUsername("张三");
        user.setAge(20);
        user.setEmail("zhangsan@example.com");
        user.setCreateTime(LocalDateTime.now());
        // insert 方法返回受影响行数
        int rows = userMapper.insert(user);
        System.out.println("新增成功,受影响行数:" + rows + ",主键:" + user.getId());
    }

    // 2. 根据 ID 查询
    @Test
    public void testSelectById() {
        User user = userMapper.selectById(1L);
        System.out.println("查询结果:" + user);
    }

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

    // 4. 根据 ID 修改
    @Test
    public void testUpdateById() {
        User user = new User();
        user.setId(1L);
        user.setAge(21);  // 只修改年龄
        int rows = userMapper.updateById(user);
        System.out.println("修改成功,受影响行数:" + rows);
    }

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

用于构建复杂查询条件(替代手写 SQL),MP 提供了 QueryWrapper(普通版)和 LambdaQueryWrapper(Lambda 版,避免硬编码字段名),示例:

@Test
public void testQueryWrapper() {
    // 需求:查询年龄大于 18 且用户名包含 "张" 的用户
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
            .gt(User::getAge, 18)  // gt = greater than(大于)
            .like(User::getUsername, "张");  // like(模糊查询)

    List<User> userList = userMapper.selectList(wrapper);
    System.out.println("条件查询结果:");
    userList.forEach(System.out::println);
}

常用条件方法:

方法 说明 示例
eq 等于 eq(User::getId, 1L)
ne 不等于 ne(User::getAge, 20)
gt/ge 大于/大于等于 gt(User::getAge, 18)
lt/le 小于/小于等于 lt(User::getAge, 30)
like 模糊查询(%值%) like(User::getName, "张")
in IN 查询 in(User::getId, 1L,2L,3L)
orderByAsc 升序排序 orderByAsc(User::getAge)
3. 分页查询

MP 提供分页插件,需先配置,再使用 Page 对象实现分页:

(1)配置分页插件
package com.example.mpdemo.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;

/**
 * MyBatis-Plus 插件配置
 */
@Configuration
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加分页插件(指定数据库类型)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
(2)分页查询示例
@Test
public void testPage() {
    // 1. 构建分页对象:第 1 页,每页 2 条
    Page<User> page = new Page<>(1, 2);
    
    // 2. 执行分页查询(条件为 null 表示查询所有)
    Page<User> resultPage = userMapper.selectPage(page, null);
    
    // 3. 获取分页结果
    System.out.println("总记录数:" + resultPage.getTotal());
    System.out.println("总页数:" + resultPage.getPages());
    System.out.println("当前页数据:");
    resultPage.getRecords().forEach(System.out::println);
}
4. 通用 Service(IService)

MP 还提供了 IService<T>ServiceImpl<M,T>,封装了更上层的 CRUD(比如批量操作、链式调用),进一步简化业务层代码:

(1)Service 接口
package com.example.mpdemo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mpdemo.entity.User;

public interface UserService extends IService<User> {
}
(2)Service 实现类
package com.example.mpdemo.service.impl;

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 {
}
(3)使用示例
@Autowired
private UserService userService;

@Test
public void testService() {
    // 批量新增
    List<User> userList = List.of(
            new User(null, "李四", 22, "lisi@example.com", LocalDateTime.now()),
            new User(null, "王五", 23, "wangwu@example.com", LocalDateTime.now())
    );
    boolean success = userService.saveBatch(userList);
    System.out.println("批量新增是否成功:" + success);

    // 链式查询(IService 特有)
    List<User> list = userService.lambdaQuery()
            .gt(User::getAge, 20)
            .list();
    System.out.println("链式查询结果:");
    list.forEach(System.out::println);
}

三、常用进阶特性

  1. 主键策略:通过 @TableId(type = IdType.XXX) 指定,常用:
    • AUTO:数据库自增(需数据库表设置自增);
    • ASSIGN_ID:雪花算法生成 Long 型主键(默认);
    • ASSIGN_UUID:生成 UUID 字符串主键。
  2. 逻辑删除:通过 @TableLogic 注解实现(标记删除字段,删除时仅修改字段值,而非物理删除);
  3. 自动填充:通过 @TableField(fill = FieldFill.XXX) 配合 MetaObjectHandler 实现创建时间、修改时间等字段自动填充;
  4. 多表查询:MP 不直接封装多表,但可结合 Wrapper 自定义 SQL 或使用注解实现。

总结

  1. 核心优势:MyBatis-Plus 基于 MyBatis 增强,无需编写基础 CRUD SQL,通过 BaseMapper/IService 快速实现单表操作;
  2. 核心组件BaseMapper(Mapper 层基础 CRUD)、Wrapper(条件构造器)、IService(Service 层高级 CRUD)是使用核心;
  3. 关键配置:分页需配置插件,主键策略可全局配置或局部注解指定,条件查询优先使用 LambdaQueryWrapper 避免字段硬编码。

掌握以上内容,即可满足日常 80% 以上的单表开发场景,大幅减少重复代码编写。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐