MyBatis-Plus Service/ServiceImpl/IService 核心关系

相信很多刚用 MyBatis-Plus(MP)的新手,都会被 IService、ServiceImpl、自定义 Service 接口/实现类 这一套层级搞懵,尤其是分不清接口和实现类的关系、各自的作用。结合自己的学习梳理,把这部分核心逻辑讲透,新手看完直接上手无压力。

一、核心层级关系(重中之重)

先上一张极简层级图,一眼看懂依赖关系:

IService(MP 自带接口) ← 自定义 Service 接口(如 BmSealRecordService)

复制代码
  ServiceImpl(MP 自带实现类) ← 自定义 Service 实现类(如 BmSealRecordServiceImpl)

对应的代码结构(以印章记录模块为例):

// 1. MP 自带接口(定义方法名,无实现)

public interface IService {

boolean save(T entity);

boolean removeById(Serializable id);

T getById(Serializable id);

// 更多CRUD方法声明...

}

// 2. 自定义 Service 接口(继承IService,复用方法名)

public interface BmSealRecordService extends IService {

// 可新增自定义业务方法(可选)

}

// 3. MP 自带实现类(实现IService,提供方法代码)

public class ServiceImpl<M extends BaseMapper, T> implements IService {

// 实现了IService所有方法,底层调用BaseMapper操作数据库

@Override

public boolean save(T entity) {

return baseMapper.insert(entity) > 0;

}

// 更多方法实现...

}

// 4. 自定义 Service 实现类(核心)

@Service

public class BmSealRecordServiceImpl

extends ServiceImpl<BmSealRecordMapper, BmSealRecord>

implements BmSealRecordService {

// 继承ServiceImpl,拿到所有方法实现;实现自定义接口,对外暴露

}

二、各组件核心作用(通俗解读)

  1. IService(MP 自带接口)
  • 本质:方法声明的集合,只定义 CRUD 方法的名称、参数、返回值,没有任何代码实现。
  • 作用:制定通用 CRUD 规范,统一所有 Service 接口的方法名,避免混乱。
  • 核心:提供 save、removeById、getById、list 等几十种常用 CRUD 方法的"规矩"。
  1. 自定义 Service 接口(如 BmSealRecordService)
  • 本质:继承 IService,将 MP 通用的方法名"复制"到自己的接口中,成为专属业务接口。

  • 作用:

    • 对外暴露业务方法,供 Controller 调用(遵循 Spring 面向接口编程规范)。
    • 可扩展自定义业务方法(如 seal() 盖章逻辑、checkSealCount() 印章次数校验)。
  • 关键:无需重新写 CRUD 方法名,继承 IService 即可复用,减少重复代码。

  1. ServiceImpl(MP 自带实现类)
  • 本质:IService 的实现类,已经写好了所有 IService 方法的具体代码。
  • 作用:封装了 CRUD 的底层逻辑,底层调用 BaseMapper(Mapper 接口)操作数据库,我们无需自己写 SQL。
  • 核心:继承它,就相当于"白嫖"了所有 CRUD 方法的实现,不用自己手写增删改查代码。
  1. 自定义 Service 实现类(如 BmSealRecordServiceImpl)
  • 本质:同时继承 ServiceImpl(拿方法实现)、实现自定义 Service 接口(守规范)。

  • 作用:

    • 继承 ServiceImpl:获得所有 CRUD 方法的实现代码,无需自己写。
    • 实现自定义 Service 接口:对外承诺"我实现了这些方法",让 Spring 能识别并注入,供 Controller 调用。
  • 关键:可重写 IService 方法,添加自己的业务逻辑(如删除时记录日志、新增时自动填充字段)。

    三、核心疑问解答(新手高频)

    疑问1:IService 的方法和 ServiceImpl 的方法是什么关系?

    一一对应,标准的「接口 ↔ 实现类」关系:

  • IService 定义"方法名"(规矩);

  • ServiceImpl 实现"方法代码"(干活);

  • 自定义实现类继承 ServiceImpl,就拿到了"规矩+干活"的完整能力。

    疑问2:为什么非要自定义 Service 接口?直接用 IService 不行吗?

    不行,核心原因2点:

  • Controller 不能直接注入 IService(IService 是泛型,Spring 无法确定要注入哪个实体的实现);

  • 自定义接口可扩展自己的业务方法,而 IService 只有通用 CRUD,满足不了实际业务需求。

    疑问3:为什么自定义实现类要同时继承 ServiceImpl 和实现自定义接口?

    Java 规定"单继承、多实现",MP 正是利用这一点设计:

  • 继承 ServiceImpl:快速获得 CRUD 方法实现,省掉90%的重复代码;

  • 实现自定义接口:遵循面向接口编程规范,供 Controller 注入调用,降低耦合。

    疑问4:如何重写 IService 的方法(添加自定义逻辑)?

    直接在自定义 Service 实现类中用 @Override 覆盖即可,示例(重写 removeById 加日志):

    @Service

    public class BmSealRecordServiceImpl

    extends ServiceImpl<BmSealRecordMapper, BmSealRecord>

    implements BmSealRecordService {

    // 重写IService的removeById方法

    @Override

    public boolean removeById(Serializable id) {

    // 1. 自定义业务逻辑(如记录删除日志)

    System.out.println("删除印章记录,ID:" + id);

    // 2. 调用父类(ServiceImpl)的原有逻辑(底层软删除)

    return super.removeById(id);

    }

    }

说明:加 super.方法名() 会保留 MP 原有逻辑,不加则完全自定义实现。

四、Controller 调用逻辑(闭环)

Controller 只需要注入「自定义 Service 接口」,Spring 会自动注入它的实现类(自定义 ServiceImpl),调用方法时,实际执行的是 ServiceImpl 里的代码(或你重写后的逻辑)。

@RestController

@RequestMapping("/sealRecord")

public class BmSealRecordController {

复制代码
// 注入自定义Service接口(不是实现类)
@Resource
private BmSealRecordService bmSealRecordService;

// 调用的是ServiceImpl里的实现(或重写后的逻辑)
@DeleteMapping("/del/{id}")
public Boolean del(@PathVariable Long id) {
    return bmSealRecordService.removeById(id);
}

}

五、终极总结(新手必背)

  1. IService:定规矩(方法名),无实现;
  2. ServiceImpl:守规矩(实现方法),干实事;
  3. 自定义 Service 接口:继承规矩,可加新规矩;
  4. 自定义 ServiceImpl:继承实干家,遵守自己的规矩;
  5. Controller:找自己的规矩(自定义接口),调用实干家(实现类)的方法。
    这套设计的核心目的:减少重复 CRUD 代码,遵循面向接口编程规范,方便扩展和维护,这也是 MP 能大幅提高开发效率的关键之一。
相关推荐
m0_739030002 小时前
mabatis-plus 和mabatis 的区别
java·数据库·mybatis
步菲11 小时前
【Java泛型擦除】一次 MyBatis 返回值不一致引发的线上故障复盘
mybatis
武子康1 天前
Java-01 深入浅出 MyBatis 入门与核心原理:半自动 ORM 框架详解
java·后端·mybatis
环流_2 天前
Redis:epoll和IO多路复用
java·redis·mybatis
欢璃2 天前
表白墙案例
java·开发语言·jvm·spring boot·spring·maven·mybatis
贫民窟的勇敢爷们2 天前
SpringBoot整合MyBatis-Plus极致实战,高效实现数据库CRUD与分页条件查询
数据库·spring boot·mybatis
暗暗别做白日梦2 天前
MyBatis-Plus 分页查询@Param 注解
mybatis
是梦终空4 天前
计算机源码273—基于SpringBoot+Vue3停车场管理系统带支沙箱支付(源代码+数据库)
数据库·spring boot·vue·mybatis·停车场管理系统·沙箱支付·毕设设计