MyBatis-Plus 全面讲解:从基础到实战
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 层推荐继承 IService
和 ServiceImpl
,提供更丰富的批量操作、事务支持等:
// 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 或测试类中注入 UserMapper
或 UserService
,直接调用方法:
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", "张") |
in | IN 查询 | in("id", 1, 2, 3) |
between | BETWEEN 查询 | between("age", 20, 30) |
orderByAsc | 升序排序 | orderByAsc("age") |
orderByDesc | 降序排序 | orderByDesc("id") |
3. 分页插件:一键实现分页
MP 内置分页插件,支持多种数据库,无需手动编写 LIMIT
或 ROW_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 层提供的链式查询,依赖 Mapper | Service 层的业务查询,支持复杂逻辑 |
实际开发中,推荐在 Service 层使用 query()
链式方法(第二种的完整场景),既保持代码简洁,又避免 AR 模式的实体类与数据库操作耦合。
七、常见问题与最佳实践
1. 常见问题
- 表名 / 字段名与关键字冲突:使用
@TableName(value = "
user")
或@TableField(value = "
order")
包裹(反引号)。 - 分页插件不生效:检查是否忘记配置
MybatisPlusInterceptor
或数据库类型是否正确。 - 逻辑删除后查询仍能查到:确保实体类添加了
@TableLogic
且数据库字段默认值为 0。
2. 最佳实践
- 优先使用 Service 层:
IService
提供了更丰富的批量操作(如saveBatch
、removeByIds
)和事务支持。 - 合理使用条件构造器:复杂条件推荐用
QueryWrapper
,简单条件可直接用lambda
表达式(LambdaQueryWrapper
)。 - 生产环境关闭 SQL 日志:
mybatis-plus.configuration.log-impl
仅在开发环境开启。 - 配合 Lombok 使用:减少
getter/setter
代码,提高开发效率。
八、总结
MyBatis-Plus 是 MyBatis 的「增强工具」,而非「替代工具」,它在保留 MyBatis 灵活性的同时,通过 通用 CRUD、条件构造器、分页插件、代码生成器 等功能大幅简化了持久层开发。
掌握 MP 后,开发者可从重复的 SQL 编写中解放出来,专注于业务逻辑实现,尤其适合快速开发中小型项目。对于复杂场景,MP 也支持无缝集成自定义 SQL,兼顾了效率与灵活性。
官方文档:https://baomidou.com/(建议常备,查看最新功能和配置)。
本文系作者 @xiin 原创发布在To Future$站点。未经许可,禁止转载。
暂无评论数据