MyBatis-Plus(简称 MP)是一款 基于 MyBatis 的增强工具,遵循「开箱即用、简化开发」的设计理念。它在 MyBatis 原有功能的基础上,提供了 CRUD 接口自动生成、条件构造器、分页插件、逻辑删除 等实用功能,彻底避免了重复的 XML 配置和 SQL 编写,大幅提升持久层开发效率。

一、MyBatis-Plus 核心优势

相比原生 MyBatis,MP 的核心价值在于「减少编码量」和「降低学习成本」,具体优势如下:

优势说明
无侵入性完全基于 MyBatis 扩展,不改变原有 MyBatis 用法,项目可平滑迁移
CRUD 自动生成内置通用 Mapper/Service 接口,无需编写 XML 和 Mapper 方法即可实现增删改查
条件构造器提供 QueryWrapper/UpdateWrapper,支持链式编程拼接复杂 SQL 条件
分页插件内置分页功能,支持 MySQL、Oracle、SQL Server 等多种数据库,配置简单
逻辑删除一键开启逻辑删除(仅标记删除状态,不物理删除数据),无需手动写 SQL
代码生成器支持基于数据库表结构自动生成 Entity、Mapper、Service、Controller 代码
全局配置支持全局 SQL 注入、全局主键策略、全局字段填充等,统一项目规范

二、环境准备:快速集成 MyBatis-Plus

MP 的集成非常简单,以 Spring Boot + MySQL 环境为例,步骤如下:

1. 引入依赖(Maven)

pom.xml 中添加 MP 核心依赖(无需额外引入 MyBatis,MP 已包含):

<!-- MyBatis-Plus 核心依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.4.1</version> <!-- 推荐使用最新稳定版 -->
</dependency>

<!-- MySQL 驱动(根据数据库版本选择,8.x 需指定 serverTimezone) -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.32</version>
    <scope>runtime</scope>
</dependency>

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

2. 配置数据库连接(application.yml)

在 Spring Boot 配置文件中配置数据库信息和 MP 基础配置:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver  # MySQL 8.x 驱动
    url: jdbc:mysql://localhost:3306/mp_demo?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
    username: root
    password: 123456

# MyBatis-Plus 配置
mybatis-plus:
  mapper-locations: classpath:mapper/**/*.xml  # Mapper XML 文件路径(可选,自动生成时可省略)
  type-aliases-package: com.example.mpdemo.entity  # 实体类包路径(简化 XML 中类名)
  configuration:
    map-underscore-to-camel-case: true  # 开启下划线转驼峰(如数据库字段 user_name → 实体类 userName)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 打印 SQL 日志(开发环境推荐开启)

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

三、核心功能实战

1. 通用 CRUD:无需编写 SQL 的「懒人工具」

MP 提供了 BaseMapper(Mapper 层)IService/ServiceImpl(Service 层) 两个通用接口,内置了 17+ 常用 CRUD 方法,直接继承即可使用。

步骤 1:定义实体类(Entity)

使用 @TableName@TableId@TableField 等注解映射数据库表和字段:

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/toString 等
@TableName("user")  // 映射数据库表名(若表名与类名一致,可省略)
public class User {
    // 主键:自增策略(支持 AUTO、INPUT、UUID 等多种策略)
    @TableId(type = IdType.AUTO)
    private Long id;
    
    // 普通字段:若字段名与属性名一致(下划线转驼峰生效),可省略 @TableField
    private String name;
    
    private Integer age;
    
    // 数据库字段为 email,属性名一致,无需额外配置
    private String email;
}

步骤 2:定义 Mapper 接口(继承 BaseMapper)

无需编写任何方法,直接继承 BaseMapper<User>

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mpdemo.entity.User;

public interface UserMapper extends BaseMapper<User> {
    // 无需手动添加 CRUD 方法,BaseMapper 已内置
}

步骤 3:定义 Service 层(可选,推荐)

Service 层推荐继承 IServiceServiceImpl,提供更丰富的批量操作、事务支持等:

// Service 接口(继承 IService)
public interface UserService extends IService<User> {
    // 可添加自定义业务方法
}

// Service 实现类(继承 ServiceImpl,注入 Mapper)
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    // 无需手动实现 CRUD 方法,ServiceImpl 已内置
}

步骤 4:使用通用 CRUD 方法

在 Controller 或测试类中注入 UserMapperUserService,直接调用方法:

import com.example.mpdemo.entity.User;
import com.example.mpdemo.mapper.UserMapper;
import com.example.mpdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
    @Autowired
    private UserMapper userMapper;  // 注入 Mapper
    
    @Autowired
    private UserService userService;  // 注入 Service

    // 1. 查询所有用户(Mapper 方式)
    @GetMapping("/users/mapper")
    public List<User> getAllByMapper() {
        return userMapper.selectList(null);  // selectList 参数为条件构造器,null 表示无条件
    }

    // 2. 查询所有用户(Service 方式)
    @GetMapping("/users/service")
    public List<User> getAllByService() {
        return userService.list();  // Service 层简化方法
    }

    // 3. 新增用户
    @GetMapping("/users/save")
    public boolean saveUser() {
        User user = new User();
        user.setName("张三");
        user.setAge(25);
        user.setEmail("zhangsan@example.com");
        return userMapper.insert(user) > 0;  // Mapper 方式:返回受影响行数
        // return userService.save(user);  // Service 方式:返回布尔值
    }

    // 4. 根据 ID 更新用户
    @GetMapping("/users/update")
    public boolean updateUser() {
        User user = new User();
        user.setId(1L);  // 必须指定主键
        user.setAge(26); // 仅更新指定字段
        return userMapper.updateById(user) > 0;
    }

    // 5. 根据 ID 删除用户
    @GetMapping("/users/delete")
    public boolean deleteUser() {
        return userMapper.deleteById(1L) > 0;
    }
}

2. 条件构造器:灵活拼接复杂 SQL

当需要查询「年龄大于 20 且邮箱包含 @example.com」这类复杂条件时,MP 提供的 QueryWrapper(查询条件)UpdateWrapper(更新条件) 可以通过链式编程快速拼接 SQL,无需手动写 XML。

示例 1:查询条件(QueryWrapper)

// 需求:查询年龄 > 20 且邮箱包含 "example" 的用户,按年龄降序排序
@GetMapping("/users/query")
public List<User> queryUsers() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.gt("age", 20)  // gt = greater than:age > 20
           .like("email", "example")  // like:email LIKE '%example%'
           .orderByDesc("age");  // 按 age 降序
    
    return userMapper.selectList(wrapper);
}

生成的 SQL 如下:

SELECT id,name,age,email FROM user WHERE (age > ? AND email LIKE ?) ORDER BY age DESC

示例 2:更新条件(UpdateWrapper)

// 需求:将 name 为 "张三" 的用户年龄更新为 28,邮箱更新为 "new_zhangsan@example.com"
@GetMapping("/users/update/wrapper")
public boolean updateByWrapper() {
    UpdateWrapper<User> wrapper = new UpdateWrapper<>();
    wrapper.set("age", 28)  // 更新字段:age = 28
           .set("email", "new_zhangsan@example.com")  // 更新字段:email = ?
           .eq("name", "张三");  // 条件:name = "张三"
    
    return userMapper.update(null, wrapper);  // 第一个参数为 null,表示不基于实体更新
}

生成的 SQL 如下:

UPDATE user SET age=?, email=? WHERE (name = ?)

常用条件构造器方法

方法说明示例
eq等于(=)eq("name", "张三")
ne不等于(!=)ne("age", 20)
gt/ge大于(>)/ 大于等于(>=)gt("age", 20)
lt/le小于(<)/ 小于等于(<=)lt("age", 30)
like模糊查询(% 值 %)like("email", "example")
likeLeft左模糊(% 值)likeLeft("name", "张")
inIN 查询in("id", 1, 2, 3)
betweenBETWEEN 查询between("age", 20, 30)
orderByAsc升序排序orderByAsc("age")
orderByDesc降序排序orderByDesc("id")

3. 分页插件:一键实现分页

MP 内置分页插件,支持多种数据库,无需手动编写 LIMITROW_NUMBER() 语句。

步骤 1:配置分页插件

创建 MP 配置类,注册分页插件:

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 分页插件(根据数据库类型选择,如 DbType.ORACLE)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

步骤 2:使用分页查询

通过 Page 对象指定页码和每页条数,结合条件构造器实现分页:

// 需求:查询第 1 页,每页 2 条数据,且年龄 > 20
@GetMapping("/users/page")
public IPage<User> pageUsers() {
    // 1. 创建 Page 对象:参数1=当前页码(从1开始),参数2=每页条数
    Page<User> page = new Page<>(1, 2);
    
    // 2. 条件构造器:年龄 > 20
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.gt("age", 20);
    
    // 3. 调用分页查询方法
    IPage<User> userPage = userMapper.selectPage(page, wrapper);
    
    // 4. 获取分页信息
    System.out.println("总记录数:" + userPage.getTotal());  // 总条数
    System.out.println("总页数:" + userPage.getPages());    // 总页数
    System.out.println("当前页数据:" + userPage.getRecords());  // 当前页列表
    
    return userPage;
}

生成的 SQL 如下(自动拼接 LIMIT):

SELECT id,name,age,email FROM user WHERE (age > ?) LIMIT ?,?

4. 逻辑删除:避免数据物理删除

逻辑删除是指「仅标记数据为删除状态,不实际从数据库删除」,MP 支持一键开启逻辑删除,无需手动写删除条件。

步骤 1:数据库添加逻辑删除字段

user 表中添加 is_deleted 字段(tinyint(1) 类型,默认值 0):

  • 0:未删除
  • 1:已删除

步骤 2:实体类添加注解

在实体类的逻辑删除字段上添加 @TableLogic 注解:

@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    
    // 逻辑删除字段:0=未删除,1=已删除
    @TableLogic
    private Integer isDeleted;
}

步骤 3:配置逻辑删除(可选)

若字段名或默认值与 MP 默认配置(is_deleted、0 = 未删、1 = 已删)不一致,可在 application.yml 中配置:

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: isDeleted  # 全局逻辑删除字段名(可选)
      logic-delete-value: 1          # 逻辑已删除值(默认 1)
      logic-not-delete-value: 0      # 逻辑未删除值(默认 0)

步骤 4:使用逻辑删除

调用 deleteById 时,MP 会自动将「物理删除」改为「更新逻辑删除字段」:

// 调用删除方法
userMapper.deleteById(1L);

生成的 SQL 如下(并非 DELETE,而是 UPDATE):

UPDATE user SET is_deleted=1 WHERE id=? AND is_deleted=0

同时,查询时会自动过滤已删除数据(无需手动加 is_deleted=0 条件):

SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0

四、高级功能:代码生成器

MP 提供 AutoGenerator 工具,可基于数据库表结构自动生成 Entity、Mapper、Mapper XML、Service、Controller 代码,彻底告别重复编码。

1. 引入代码生成器依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.4.1</version>
</dependency>

<!-- 模板引擎(MP 代码生成器依赖 Freemarker) -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.32</version>
    </version>
</dependency>

2. 编写代码生成器配置类

创建一个 CodeGenerator 类,配置数据库连接、包路径、生成策略等:

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) {
        // 1. 配置数据库连接
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp_demo?useSSL=false&serverTimezone=UTC", "root", "123456")
                // 2. 全局配置
                .globalConfig(builder -> {
                    builder.author("yourName") // 设置作者
                            .outputDir(System.getProperty("user.dir") + "/src/main/java") // 生成路径(项目的 java 目录)
                            .commentDate("yyyy-MM-dd") // 注释日期格式
                            .disableOpenDir(); // 生成后不打开文件夹
                })
                // 3. 包配置(生成的类放在哪个包下)
                .packageConfig(builder -> {
                    builder.parent("com.example.mpdemo") // 父包名
                            .moduleName("") // 子模块名(无则留空)
                            .entity("entity") // 实体类包名
                            .mapper("mapper") // Mapper 接口包名
                            .service("service") // Service 接口包名
                            .serviceImpl("service.impl") // Service 实现类包名
                            .controller("controller") // Controller 包名
                            .xml("mapper.xml") // Mapper XML 包名
                            .pathInfo(Collections.singletonMap(OutputFile.xml, 
                                    System.getProperty("user.dir") + "/src/main/resources/mapper")); // XML 生成路径
                })
                // 4. 策略配置
                .strategyConfig(builder -> {
                    builder.addInclude("user") // 指定要生成的表名(可多个,如 "user", "order")
                            .addTablePrefix("t_", "sys_") // 过滤表前缀(如 t_user → 实体类为 User)
                            
                            // 实体类策略
                            .entityBuilder()
                            .enableLombok() // 开启 Lombok
                            .enableTableFieldAnnotation() // 为字段添加 @TableField 注解
                            .logicDeleteColumnName("is_deleted") // 逻辑删除字段
                            
                            // Controller 策略
                            .controllerBuilder()
                            .enableRestStyle() // 开启 RESTful 风格(生成 @RestController)
                            .enableHyphenStyle() // 开启 URL 下划线转驼峰(如 /user_info → UserInfoController)
                            
                            // Service 策略
                            .serviceBuilder()
                            .formatServiceFileName("%sService") // Service 接口名格式(如 UserService)
                            .formatServiceImplFileName("%sServiceImpl"); // Service 实现类名格式
                })
                // 5. 模板引擎(使用 Freemarker)
                .templateEngine(new FreemarkerTemplateEngine())
                // 6. 执行生成
                .execute();
    }
}

3. 运行生成器

运行 CodeGenerator.main() 方法,即可在指定目录生成全套代码,包括:

  • entity/User.java(实体类)
  • mapper/UserMapper.java(Mapper 接口)
  • mapper/xml/UserMapper.xml(Mapper XML)
  • service/UserService.java(Service 接口)
  • service/impl/UserServiceImpl.java(Service 实现类)
  • controller/UserController.java(Controller)

五、全局配置与扩展

1. 全局主键策略

通过全局配置统一主键生成策略,避免在每个实体类上重复配置 @TableId

mybatis-plus:
  global-config:
    db-config:
      id-type: auto  # 全局主键自增(可选:AUTO、INPUT、UUID、ID_WORKER 等)

2. 字段自动填充

对于「创建时间」create_time、「更新时间」update_time 等需要自动维护的字段,MP 提供字段填充功能:

步骤 1:实体类添加注解

@Data
@TableName("user")
public class User {
    // ... 其他字段
    
    // 插入时自动填充
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    // 插入和更新时自动填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}

步骤 2:实现填充处理器

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) {
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }

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

3. 自定义 SQL(兼容 MyBatis)

当 MP 通用方法无法满足需求时,可像原生 MyBatis 一样编写自定义 SQL:

步骤 1:在 Mapper 接口添加方法

public interface UserMapper extends BaseMapper<User> {
    // 自定义方法:根据姓名查询用户
    User selectByUserName(@Param("name") String name);
}

步骤 2:在 XML 中编写 SQL

UserMapper.xml 中添加:

<mapper namespace="com.example.mpdemo.mapper.UserMapper">
    <!-- 自定义查询 -->
    <select id="selectByUserName" resultType="com.example.mpdemo.entity.User">
        SELECT * FROM user WHERE name = #{name} AND is_deleted = 0
    </select>
</mapper>

你提到的 User user = query().eq("phone", phone).one(); 是 MyBatis-Plus 中 Active Record 模式的用法,这是一种将实体类与数据库操作直接绑定的编程模式,我在之前的讲解中没有详细提及,这里补充说明:

六、Active Record 模式

Active Record(简称 AR)是一种设计模式,它将 实体类与数据库操作 结合,让实体类本身具备 CRUD 能力。在 MyBatis-Plus 中,只需让实体类继承 Model<T> 类,即可直接通过实体对象调用数据库方法,无需注入 Mapper 或 Service。

代码示例解析

1. 实体类继承 Model<T>

首先需要让实体类继承 Model<User>(泛型为当前实体类):

import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;

@Data
public class User extends Model<User> {  // 继承 Model
    private Long id;
    private String name;
    private Integer age;
    private String phone;  // 手机号字段
}

2. 使用 AR 模式的查询方法

此时就可以通过实体对象直接调用 query() 方法构建查询条件:

// 查询手机号为指定值的用户
String phone = "13800138000";
User user = new User().query().eq("phone", phone).one();
  • new User().query():创建查询构造器(类似 QueryWrapper
  • .eq("phone", phone):添加条件(phone 字段等于指定值)
  • .one():执行查询并返回单个结果(若存在多条,会抛出异常)

AR 模式的常用方法

除了查询,AR 模式还支持其他 CRUD 操作:

// 1. 新增(save 方法)
User user = new User();
user.setName("李四");
user.setPhone("13900139000");
boolean saveSuccess = user.save();  // 插入数据

// 2. 更新(update 方法)
user.setAge(30);
boolean updateSuccess = user.updateById();  // 根据 ID 更新

// 3. 删除(delete 方法)
boolean deleteSuccess = user.deleteById(1L);  // 根据 ID 删除

// 4. 查询(更多示例)
User user = new User().query().eq("name", "张三").one();  // 查单个
List<User> userList = new User().query().gt("age", 20).list();  // 查列表

AR 模式的优缺点

特点说明
优点代码更简洁,无需注入 Mapper/Service,直接通过实体类操作数据库
缺点实体类与数据库操作耦合,不适合复杂业务场景;依赖无参构造器和继承关系

适用场景

AR 模式适合 简单的单表操作,如快速查询、新增单条数据等。对于复杂业务(如多表关联、事务管理),仍推荐使用 Mapper 或 Service 层的方式。

如果需要使用 AR 模式,记得在实体类继承 Model<T> 后,确保 Mapper 接口已继承 BaseMapper(否则会报错):

public interface UserMapper extends BaseMapper<User> {
    // 无需额外方法,BaseMapper 已足够
}

一个常见问题

User user = new User().query().eq("name", "张三").one(); 和 User user = query().eq("name", "张三").one(); 一样吗?

这两种写法不一样,核心区别在于是否通过实体类实例调用 query() 方法,对应的功能和使用场景也不同:

1. new User().query().eq("name", "张三").one()

这是 Active Record 模式(AR 模式) 的用法:

  • 必须让 User 类继承 MyBatis-Plus 的 Model<User> 类(public class User extends Model<User>
  • new User() 创建实体类实例,通过实例调用 query() 方法生成查询构造器
  • 本质是通过实体类自身发起查询,无需依赖 Mapper 或 Service 注入
  • 适用于简单的单表查询,代码简洁但耦合实体类与数据库操作

2. query().eq("name", "张三").one()

这种写法不完整,需要结合具体场景理解:

  • 若在 Service 实现类 中使用(如 UserServiceImpl),实际是 this.query() 的简写,这里的 query()ServiceImpl 类提供的方法

    // Service 实现类中(继承了 ServiceImpl<UserMapper, User>)
    public User findUser() {
        return query().eq("name", "张三").one(); // 等价于 this.query()
    }

    此时的 query() 是 Service 层提供的查询构造器入口,最终依赖注入的 Mapper 执行查询,属于Service 层的链式查询方式,无需手动创建 QueryWrapper

  • 若在其他场景(如 Controller)直接写 query(),会报「无法解析方法 query ()」错误,因为普通类中没有这个方法。

核心区别总结

写法依赖条件本质适用场景
new User().query()User 类必须继承 Model<T>AR 模式,实体类自身发起查询简单单表操作,不依赖 Mapper/Service 注入
query()(Service 中)类需继承 ServiceImpl<Mapper, Entity>Service 层提供的链式查询,依赖 MapperService 层的业务查询,支持复杂逻辑

实际开发中,推荐在 Service 层使用 query() 链式方法(第二种的完整场景),既保持代码简洁,又避免 AR 模式的实体类与数据库操作耦合。

七、常见问题与最佳实践

1. 常见问题

  • 表名 / 字段名与关键字冲突:使用 @TableName(value = "user")@TableField(value = "order") 包裹(反引号)。
  • 分页插件不生效:检查是否忘记配置 MybatisPlusInterceptor 或数据库类型是否正确。
  • 逻辑删除后查询仍能查到:确保实体类添加了 @TableLogic 且数据库字段默认值为 0。

2. 最佳实践

  • 优先使用 Service 层IService 提供了更丰富的批量操作(如 saveBatchremoveByIds)和事务支持。
  • 合理使用条件构造器:复杂条件推荐用 QueryWrapper,简单条件可直接用 lambda 表达式(LambdaQueryWrapper)。
  • 生产环境关闭 SQL 日志mybatis-plus.configuration.log-impl 仅在开发环境开启。
  • 配合 Lombok 使用:减少 getter/setter 代码,提高开发效率。

八、总结

MyBatis-Plus 是 MyBatis 的「增强工具」,而非「替代工具」,它在保留 MyBatis 灵活性的同时,通过 通用 CRUD、条件构造器、分页插件、代码生成器 等功能大幅简化了持久层开发。

掌握 MP 后,开发者可从重复的 SQL 编写中解放出来,专注于业务逻辑实现,尤其适合快速开发中小型项目。对于复杂场景,MP 也支持无缝集成自定义 SQL,兼顾了效率与灵活性。

官方文档:https://baomidou.com/(建议常备,查看最新功能和配置)。

分类: Java-Backend 标签: JavaMyBatis-Plus

评论

暂无评论数据

暂无评论数据

目录

目录