MyBatis-Plus 入门
作者: luote (luote) · 个人主页 luote996.cn
ORM 是什么
对象关系映射(ORM)把 Java 对象与数据库表行对应起来,避免手写大量 JDBC。MyBatis-Plus(MP)在 MyBatis 基础上提供通用 CRUD、分页、条件构造器,是 create-luote 的数据访问层方案。
实体类 PO
User.java 对应 users 表:
java
@Data
@TableName("users")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
@TableLogic
private Integer deleted;
}| 注解 | 作用 |
|---|---|
| @TableName | 指定表名 |
| @TableId | 主键及生成策略 |
| @TableLogic | 软删除字段 |
| @TableField | 字段映射、exist=false 表示非表字段 |
Mapper 接口
java
@Mapper
public interface UserMapper extends BaseMapper<User> {
}继承 BaseMapper<User> 即拥有:
| 方法 | 等价 SQL 概念 |
|---|---|
| insert | INSERT |
| deleteById | DELETE(或软删) |
| updateById | UPDATE |
| selectById | SELECT BY id |
| selectList | SELECT 列表 |
复杂 SQL 可在 mapper.xml 或使用 @Select 注解编写,脚手架简单场景用 MP 内置方法即可。
Service 层
java
public interface UserService extends IService<User> {
UserVO getCurrentUser();
}实现类继承 ServiceImpl<UserMapper, User>,可调用 save、updateById、lambdaQuery() 等。
条件构造器
java
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getDeleted, 0)
.like(StringUtils.isNotBlank(keyword), User::getUsername, keyword)
.orderByDesc(User::getCreateTime);
Page<User> page = new Page<>(pageNum, pageSize);
userMapper.selectPage(page, wrapper);LambdaQueryWrapper 用方法引用避免字段名拼写错误。
分页插件
MybatisPlusConfig 注册分页拦截器后,selectPage 会自动生成 COUNT 与 LIMIT SQL。前端传 page、size,Controller 转成 Page 对象即可。
DTO 与 VO 分离
| 类型 | 方向 | 示例 |
|---|---|---|
| DTO | 前端 → 后端 | LoginDTO、RegisterDTO |
| PO | 数据库行 | User |
| VO | 后端 → 前端 | UserVO(不含 password) |
不要在 VO 中返回密码哈希;敏感字段在 Service 层做脱敏。
常见问题
| 现象 | 原因 |
|---|---|
| 查不到刚插入的数据 | 事务未提交或读写分离延迟 |
| 字段为 null 未更新 | MP 默认忽略 null,需 UpdateWrapper.set |
| 软删后仍能查到 | 未加 @TableLogic 或未配置逻辑删值 |
与 luote 脚手架的关系
| 文件 | 说明 |
|---|---|
| mapper/UserMapper.java | 数据访问 |
| service/impl/UserServiceImpl.java | 分页查询、注册、登录校验 |
| config/MybatisPlusConfig.java | 分页、乐观锁等插件 |
| resources/data.sql | 表结构与初始数据 |