MyBatis-Plus的ActiveRecord 模式
MyBatis-Plus 的 ActiveRecord(AR)模式,这是 MyBatis-Plus 对传统 ORM 中 ActiveRecord 设计模式的实现,核心是让实体类直接继承Model类,从而让实体类自身拥有 CRUD 操作能力,无需依赖 Service/Mapper 层即可完成数据库操作,大幅简化单表操作的代码。
一、ActiveRecord 模式的核心概念
先通过一个简单的比喻理解:
• 传统模式:实体类(如SysUser)只是 “数据载体”,CRUD 需要调用UserMapper/UserService的方法(比如userService.getById(id));
• AR 模式:实体类(如SysUser)既是 “数据载体”,也是 “操作工具”,直接调用自身方法就能完成 CRUD(比如sysUser.selectById())。
二、AR 模式的使用步骤
以SysUser实体为例,一步步实现 AR 模式:
1. 基础准备(核心:实体类继承Model)
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; // 1. 继承Model<SysUser>(泛型为当前实体类) @Data @TableName("sys_user") // 关联数据库表 public class SysUser extends Model<SysUser> { // 2. 必须指定主键(MyBatis-Plus要求) @TableId(type = IdType.AUTO) private Long id; private String username; private String phone; private String password; // 其他字段... }注意!!!:
• Mapper 层仍需定义(无需写 SQL),但 Service 层可省略(仅 AR 模式下):
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; @Mapper public interface SysUserMapper extends BaseMapper<SysUser> { // 无需写任何方法,BaseMapper已包含基础CRUD }2. AR 模式核心操作(直接用实体类调用)
// 1. 新增:实体类直接调用insert() SysUser user = new SysUser(); user.setUsername("test"); user.setPhone("13800138000"); boolean saveSuccess = user.insert(); // 返回是否新增成功 // 2. 查询:实体类调用selectXXX() // 根据ID查询 SysUser queryUser = new SysUser().selectById(1L); // 条件查询(等价于你之前的Wrappers) SysUser conditionUser = new SysUser() .selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, "test")); // 3. 更新:先查后改,调用update() queryUser.setPhone("13900139000"); boolean updateSuccess = queryUser.update(); // 根据主键更新 // 4. 删除:实体类调用deleteXXX() boolean deleteSuccess = new SysUser().deleteById(1L); // 根据ID删除三、AR 模式的核心特点
| 特性 | 说明 |
|---|---|
| 极简代码 | 无需注入 Service/Mapper,实体类自身即可完成 CRUD,减少模板代码 |
| 与 MyBatis-Plus 兼容 | 支持 Wrappers 条件构造器、分页、主键策略等所有 MyBatis-Plus 核心功能 |
| 单表操作友好 | 特别适合简单的单表 CRUD 场景(如你的用户详情查询),代码更直观 |
| 依赖 BaseMapper | 仍需定义 Mapper 接口并继承 BaseMapper(MyBatis-Plus 底层需要) |
| 不适合复杂业务 | 多表联查、事务控制、复杂逻辑仍需用 Service 层,AR 模式仅适合单表操作 |
四、AR 模式 vs 传统 Service/Mapper 模式
传统模式:
// 依赖Service层,通过service调用方法 SysUser sysUser = userService.getOne(Wrappers.query(query), false);改用 AR 模式后,代码可简化为:
// 无需注入userService,直接用实体类查询 SysUser sysUser = new SysUser() .selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getId, query.getId()), false);五、AR 模式的适用场景 & 注意事项
适用场景
1. 简单单表 CRUD(如用户、角色、字典等基础表);
2. 快速开发原型、小项目(减少分层代码,提升开发效率);
3. 临时的数据库操作(如脚本、工具类)。
注意事项(避坑关键)
1. 不要过度依赖 AR 模式:
复杂业务(多表联查、事务、权限校验)仍需用 Service 层,AR 模式仅作为单表操作的补充;
2. 主键必须指定:
继承Model后,必须通过@TableId指定主键字段,否则 AR 方法会报错;
3. 性能与传统模式一致:
底层还是调用 BaseMapper 的方法,性能无差异,只是代码写法不同;
4. 异常处理:
AR 方法的返回值多为boolean(是否成功),查询方法返回null(无数据),需自行处理空指针。
总结
1. MyBatis-Plus 的 AR 模式是实体类继承 Model 后拥有 CRUD 能力的设计模式,核心是简化单表操作代码;
2. 优势是极简、直观,适合简单单表场景;劣势是不适合复杂业务,需配合 Service 层使用;
3. 在日常开发中,可在用户、角色等基础表的单表操作中使用 AR 模式,减少模板代码,复杂逻辑仍保留 Service 层;
4.可以让实体类继承Model类,同时混用 AR 模式和传统的 Service/Mapper 模式——MyBatis-Plus 本身就设计为兼容这两种模式,不会有冲突,反而能根据场景灵活选择,这也是实际开发中最常用的做法。
