news 2026/10/23 9:26:51

理解mybatis向上抽取的概念

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
理解mybatis向上抽取的概念

1. 先理解 “向上抽取” 的核心概念

“向上抽取” 本质是面向抽象编程 + 通用逻辑复用的设计思想:把数据库操作(CRUD)中重复、通用、固定的逻辑从业务代码中抽离出来,封装到更上层的抽象层(比如通用父类 / 接口),让业务代码只需要关注自身的个性化逻辑,无需重复编写模板化代码。

MyBatis-Plus 正是基于这个思想,对原生 MyBatis 的 CRUD 操作做了极致的 “向上抽取”,核心解决的问题是:避免每个 Mapper/Service 都重复写相同的增删改查方法。

2. MyBatis-Plus 向上抽取的分层实现

MyBatis-Plus 的抽取逻辑主要体现在Mapper 层和Service 层两个核心层级,我们逐层拆解:

2.1 第一步:Mapper 层的抽取(基础核心)

原生 MyBatis 中,你需要为每个实体的 Mapper 接口手动定义 CRUD 方法(如insertUser、selectUserById),而 MP 把这些通用方法抽取到了BaseMapper<T>这个抽象接口中。

核心实现逻辑

封装所有通用CRUD方法

只关注个性化SQL

只关注个性化SQL

BaseMapper 抽象接口

UserMapper 业务Mapper

OrderMapper 业务Mapper

ProductMapper 业务Mapper

用户表个性化查询

订单表个性化查询

graph TD A[BaseMapper<T> 抽象接口] -->|封装所有通用CRUD方法| B[UserMapper 业务Mapper] A --> C[OrderMapper 业务Mapper] A --> D[ProductMapper 业务Mapper] B -->|只关注个性化SQL| E[用户表个性化查询] C -->|只关注个性化SQL| F[订单表个性化查询]

封装所有通用CRUD方法

只关注个性化SQL

只关注个性化SQL

BaseMapper 抽象接口

UserMapper 业务Mapper

OrderMapper 业务Mapper

ProductMapper 业务Mapper

用户表个性化查询

订单表个性化查询

豆包

你的 AI 助手,助力每日工作学习

代码示例:
  • MP 提供的抽象父接口BaseMapper<T>(核心抽取的通用方法):

    java

    运行

    public interface BaseMapper<T> extends Mapper<T> { // C: 新增 int insert(T entity); // D: 根据ID删除 int deleteById(Serializable id); // U: 根据ID更新 int updateById(@Param("et") T entity); // R: 根据ID查询 T selectById(Serializable id); // R: 查询所有 List<T> selectList(Wrapper<T> queryWrapper); // 还有分页查询、批量操作等数十个通用方法... }
  • 你的业务 Mapper 只需继承这个抽象接口(无需写任何通用方法):

    java

    运行

    // 继承BaseMapper<User>,自动拥有User表的所有通用CRUD方法 public interface UserMapper extends BaseMapper<User> { // 只需要写User表的个性化查询(比如复杂联表),通用方法无需重复写 List<User> selectUserByAgeRange(@Param("minAge") Integer minAge, @Param("maxAge") Integer maxAge); }
2.2 第二步:Service 层的抽取(进阶复用)

MP 不仅抽取了 Mapper 层,还对 Service 层做了更上层的抽取,提供了IService<T>接口和ServiceImpl<M, T>实现类,封装了通用的业务层逻辑(比如批量新增、分页查询、逻辑删除、乐观锁等)。

核心实现逻辑:

只关注个性化业务逻辑

只关注个性化业务逻辑

IService 抽象接口

ServiceImpl, T> 实现类

UserService 业务Service

OrderService 业务Service

用户登录/权限校验等

订单状态流转等

graph TD A[IService<T> 抽象接口] --> B[ServiceImpl<BaseMapper<T>, T> 实现类] B --> C[UserService 业务Service] B --> D[OrderService 业务Service] C -->|只关注个性化业务逻辑| E[用户登录/权限校验等] D -->|只关注个性化业务逻辑| F[订单状态流转等]

只关注个性化业务逻辑

只关注个性化业务逻辑

IService 抽象接口

ServiceImpl, T> 实现类

UserService 业务Service

OrderService 业务Service

用户登录/权限校验等

订单状态流转等

豆包

你的 AI 助手,助力每日工作学习

代码示例:
  • 业务 Service 接口继承IService<T>:

    java

    运行

    // 继承IService<User>,自动拥有User表的通用业务方法 public interface UserService extends IService<User> { // 只写User的个性化业务逻辑,通用CRUD无需重复写 boolean login(String username, String password); }
  • 业务 Service 实现类继承ServiceImpl:

    java

    运行

    @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { // 实现个性化业务逻辑 @Override public boolean login(String username, String password) { // 调用父类提供的通用查询方法 User user = lambdaQuery().eq(User::getUsername, username).one(); return user != null && user.getPassword().equals(password); } }
2.3 第三步:抽取的 “可扩展” 设计(不是硬编码)

MP 的向上抽取不是 “一刀切” 的固定逻辑,而是保留了个性化扩展的入口,体现了 “抽取通用、保留个性” 的核心思想:

  • 通用方法满足 80% 场景:比如insert、selectById、updateById等,直接用即可;
  • 个性化场景可扩展:
    • Mapper 层:通过注解 / XML 编写个性化 SQL;
    • Service 层:通过lambdaQuery()、lambdaUpdate()等链式 API 快速构建个性化查询,或重写父类方法;
    • 全局配置:通过MybatisPlusConfig自定义主键生成策略、逻辑删除字段等,让通用逻辑适配你的业务。

3. 对比原生 MyBatis,理解 “向上抽取” 的价值

表格

维度原生 MyBatisMyBatis-Plus(向上抽取)
Mapper 层代码量每个实体都要写全套 CRUD 方法 + XML只需继承 BaseMapper,零通用代码
Service 层代码量每个 Service 都要封装 CRUD 业务逻辑继承 IService/ServiceImpl,零通用代码
扩展成本新增实体需重复写模板代码,易出错只需关注个性化逻辑,扩展成本极低
维护成本通用逻辑修改需改所有 Mapper/Service通用逻辑修改只需改 MP 底层,全局生效

4. 向上抽取的底层支撑(为什么能实现)

MP 能做到高效的向上抽取,核心依赖两个技术:

  • 泛型(Generic):BaseMapper<T>、IService<T>中的<T>是实体类泛型,MP 通过泛型反射获取实体类的表名、字段名等信息,动态生成通用 SQL;
  • 动态代理(Dynamic Proxy):MP 基于 MyBatis 的动态代理机制,为继承BaseMapper的接口动态生成通用方法的实现,无需手动写 SQL。

总结

  1. MyBatis-Plus 的 “向上抽取” 核心是把通用的 CRUD 逻辑抽离到抽象层,让业务代码只关注个性化逻辑,避免重复造轮子;
  2. 抽取分为两层:BaseMapper<T>抽取代码层通用 SQL 操作,IService<T>抽取业务层通用逻辑;
  3. 抽取不是 “固定死” 的,而是保留扩展入口,通用 + 个性化结合,既提升开发效率,又满足业务定制化需求。

这种思想不仅适用于 MyBatis-Plus,也是整个 Java 开发中 “高内聚、低耦合” 设计原则的典型体现 ——将不变的部分抽象,将变化的部分留空。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 21:35:47

运算放大器:电压/电流转换

转载&#xff1a;https://zhuanlan.zhihu.com/p/647432977 电压/电流转换即V/I转换&#xff0c;是将输入的电压信号转换成满足一定关系的电流信号&#xff0c;转换后的电流相当一个输出可调的恒流源&#xff0c;其输出电流应能够保持稳定而不会随负载的变化而变化。一般来说&am…

作者头像 李华
网站建设 2026/10/22 22:22:57

2025年第十二期正式出版

Volume 3 Issue 12 封面解读 George Fu Gao / Zepeng Xu The ACE2-using coronaviruses (CoVs) have led to two outbreaks that profoundly affected the world, and continue to emerge as investigations deepen. A summarization of known ACE2-using CoVs indicates tha…

作者头像 李华
网站建设 2026/10/21 23:37:08

学长亲荐!万众偏爱的AI论文工具 —— 千笔

你是否曾为论文选题发愁&#xff0c;反复修改却仍不满意&#xff1f;是否在查重、格式、文献整理上耗费大量时间却收效甚微&#xff1f;研究生阶段的论文写作&#xff0c;本就充满挑战&#xff0c;而千笔AI正是为解决这些痛点而生。它不仅能够高效生成结构清晰的论文内容&#…

作者头像 李华
网站建设 2026/10/21 23:36:34

三个线程如何按顺序打印ABC?

这篇文章分享一道非常不错的题目&#xff1a;三个线程按序打印ABC。很多读者朋友应该都觉得这道题目不难&#xff0c;这次给大家带来十二种做法&#xff0c;一定有你没有见过的新姿势。1. synchronizedwaitnotify说到同步&#xff0c;我们很容易就想到synchronized。线程间通信…

作者头像 李华
网站建设 2026/10/23 10:07:31

骨折分类数据集-医学影像分析-6717张X光片-适用于大学生毕业设计-支持目标检测与分类模型训练-完整标注信息-骨折检测与分类-医学影像分析研究者和开发者-推动骨折检测算法的研发与优化

骨折分类数据集&#xff1a;医学影像分析的完整资源 引言与背景 在现代医学影像分析领域&#xff0c;骨折检测与分类是骨科诊断的重要环节。随着深度学习技术的快速发展&#xff0c;基于X光片的骨折自动识别系统逐渐成为辅助临床诊断的关键工具。本数据集为医学影像分析研究者…

作者头像 李华
网站建设 2026/10/22 1:27:01

php 随机红包数生成

无论哪种实现方式&#xff0c;随机红包都要遵守几个核心约束&#xff08;这是和单纯随机数最大的区别&#xff09;&#xff1a;总金额固定&#xff08;比如 100 元分 10 个红包&#xff09;&#xff1b;每个红包金额非空&#xff08;至少 0.01 元&#xff0c;避免分到 0&#x…

作者头像 李华