【Java后端】MyBatis-Plus 原理解析

MyBatis-Plus 原理解析

其实 MyBatis-Plus 的 Service 层设计 就是为了让开发者不用重复写很多样板代码。我们来一点点剖析 UserServiceImplIServiceUserServiceServiceImpl 之间的关系和调用链。


1. 类/接口关系图

复制代码
             IService<T>
                ▲
                │
        UserService (接口)   <-- 自定义的接口
                ▲
                │
 ServiceImpl<M, T> (抽象类,提供默认实现)
                ▲
                │
     UserServiceImpl (写的实现类)

2. 各个角色的作用

(1) IService<T>

  • MP 提供的 通用 Service 接口,定义了最常用的 CRUD 方法。
  • 例如:
java 复制代码
public interface IService<T> {
    boolean save(T entity);
    boolean removeById(Serializable id);
    boolean updateById(T entity);
    T getById(Serializable id);
    List<T> list();
    // ... 还有很多
}

(2) UserService

  • 你的业务接口 ,继承了 IService<User>
  • 这样 UserService 就自动拥有了所有 CRUD 方法,不用自己再声明。
  • 但你也可以在里面 加自定义业务方法
java 复制代码
public interface UserService extends IService<User> {
    User findByEmail(String email); // 自定义方法
}

(3) ServiceImpl<M, T>

  • MP 提供的 通用实现类 ,实现了 IService<T> 里的所有方法。
  • 内部通过调用 BaseMapper<T> 来完成数据库操作。

源码片段(简化):

java 复制代码
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
    @Autowired
    protected M baseMapper; // Mapper 注入进来

    @Override
    public boolean save(T entity) {
        return baseMapper.insert(entity) > 0;
    }

    @Override
    public T getById(Serializable id) {
        return baseMapper.selectById(id);
    }
}

(4) UserServiceImpl

  • 你的实现类 ,继承了 ServiceImpl<UserMapper, User> 并实现 UserService
  • 因为 ServiceImpl 已经实现了 IService 的方法,所以你啥都不用写,就自动拥有 savegetByIdlist 等方法。
  • 你可以在里面实现自定义的业务逻辑:
java 复制代码
@Service
public class UserServiceImpl 
    extends ServiceImpl<UserMapper, User> 
    implements UserService {

    @Override
    public User findByEmail(String email) {
        return lambdaQuery().eq(User::getEmail, email).one();
    }
}

3. 调用链条

比如调用 userService.save(user) 的时候,流程是这样的:

  1. Controller 调用
java 复制代码
userService.save(user);
  1. Spring 容器注入的其实是 UserServiceImpl 对象
    所以进入 UserServiceImpl.save()
  2. UserServiceImpl 继承自 ServiceImpl,没有重写 save(),于是调用的是 ServiceImpl.save()
  3. ServiceImpl.save() 内部会调用 baseMapper.insert(user) ,而 baseMapper 是注入的 UserMapper,继承了 BaseMapper<User>
  4. BaseMapper 底层最终由 MyBatis 执行 SQL,完成插入操作。

4. 关键总结

  • IService<T>定义通用方法(接口)。
  • UserService业务接口 ,扩展 IService<User>
  • ServiceImpl<M, T>默认实现 ,帮你实现了 IService 的所有方法。
  • UserServiceImpl实现类 ,继承 ServiceImpl,可以直接用 CRUD,也可以扩展业务方法。

所以:

👉 写的代码只需要关心业务逻辑,CRUD 全交给 MyBatis-Plus 的基类完成

相关推荐
咩咩啃树皮6 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
灯澜忆梦6 小时前
GO_并发编程---定时器
开发语言·后端·golang
鱟鲥鳚6 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
-银雾鸢尾-6 小时前
C#中的StringBuilder相关方法
开发语言·c#
-银雾鸢尾-7 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
大模型码小白8 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司8 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地9 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
憧憬成为web高手9 小时前
皮卡丘靶场速通--sql 2
数据库·sql·mybatis
wuqingshun31415910 小时前
TCP超时重传机制是为了解决什么问题?
java