源本科技 | 码上会

MyBatis-Plus Service Interface

2026/04/01
5
0

引言

MyBatis-Plus(简称 MP)在原生 MyBatis 基础上,对Service 层进行了深度封装,提供了通用的 IService 接口和 ServiceImpl 实现类,无需编写重复的 CRUD 模板代码,极大简化了 Service 层开发。


核心组件

MP 对 Service 层的封装基于两个核心类:

组件

作用

IService<T>

MP 提供的通用 Service 接口,定义了所有通用 CRUD、批量、分页方法

ServiceImpl<M extends BaseMapper<T>, T>

MP 提供的通用 Service 实现类,实现了 IService 接口,注入对应 Mapper

  • T:数据库实体类(如 User、Order)

  • M:继承 MP BaseMapper 的 Mapper 接口


环境准备

实体类

User 实体为例,对应数据库 user 表:

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

@Data
public class User {
    // 主键自增
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

Mapper

Mapper 接口继承 MP BaseMapper<T>

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

Service

自定义 Service 接口

自定义业务接口继承 IService<T>,即可直接使用 MP 提供的所有通用方法:

import com.baomidou.mybatisplus.extension.service.IService;

public interface UserService extends IService<User> {
    // 此处可扩展自定义业务方法
}

自定义 Service 实现

实现类继承 ServiceImpl<M, T>,并实现自定义 Service 接口:

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional // 开启事务
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    // 无需重写任何方法,直接拥有所有通用CRUD能力
    // 自定义业务方法在此实现
}

核心优势:只需继承对应接口 / 实现类,无需编写 savelistpage 等基础方法,直接调用即可。


IService 核心方法

IService 封装了单条 / 批量 CRUD、分页、条件查询、计数等常用操作,按功能分类如下:

新增(Save)

方法

作用

save(T entity)

单条插入

saveBatch(Collection<T> entityList)

批量插入(默认批次 1000)

saveBatch(Collection<T> entityList, int batchSize)

指定批次大小批量插入

saveOrUpdate(T entity)

主键存在则更新,不存在则插入

saveOrUpdateBatch(Collection<T> entityList)

批量新增或更新

// 单条新增
User user = new User();
user.setName("张三");
user.setAge(20);
userService.save(user);

// 批量新增
List<User> userList = new ArrayList<>();
userList.add(user1);
userList.add(user2);
userService.saveBatch(userList);

删除(Remove)

方法

作用

removeById(Serializable id)

根据主键删除

remove(Wrapper<T> queryWrapper)

根据条件构造器删除

removeByIds(Collection<? extends Serializable> idList)

批量根据主键删除

// 根据ID删除
userService.removeById(1L);

// 条件删除:删除年龄大于30的用户
userService.remove(Wrappers.<User>lambdaQuery().gt(User::getAge, 30));

更新(Update)

方法

作用

updateById(T entity)

根据主键更新

update(Wrapper<T> updateWrapper)

根据条件构造器更新

update(T entity, Wrapper<T> updateWrapper)

实体 + 条件更新

updateBatchById(Collection<T> entityList)

批量根据主键更新

// 根据ID更新
User user = new User();
user.setId(1L);
user.setName("李四");
userService.updateById(user);

// 条件更新
userService.update(Wrappers.<User>lambdaUpdate()
        .set(User::getAge, 25)
        .eq(User::getName, "张三"));

查询(Get/List)

方法

作用

getById(Serializable id)

根据主键查询单条

getOne(Wrapper<T> queryWrapper)

根据条件查询单条(多条抛异常)

getOne(Wrapper<T> queryWrapper, boolean throwEx)

条件查询单条,false 则返回第一条

list()

查询所有数据

list(Wrapper<T> queryWrapper)

条件查询列表

listByIds(Collection<? extends Serializable> idList)

批量根据主键查询

count()

查询总条数

count(Wrapper<T> queryWrapper)

条件查询总条数

// 根据ID查询
User user = userService.getById(1L);

// 条件列表查询:查询年龄≤25的用户
List<User> userList = userService.list(Wrappers.<User>lambdaQuery().le(User::getAge, 25));

// 统计数量
long count = userService.count(Wrappers.<User>lambdaQuery().like(User::getName, "李"));

分页(Page)

MP 集成分页插件,IService 直接提供分页方法:

// 前提:配置MyBatis-Plus分页插件
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

分页方法:

方法

作用

page(IPage<T> page)

无条件分页

page(IPage<T> page, Wrapper<T> queryWrapper)

条件分页

// 第1页,每页10条
Page<User> page = new Page<>(1, 10);
// 条件分页
Page<User> result = userService.page(page, Wrappers.<User>lambdaQuery().ge(User::getAge, 18));

// 获取分页数据
List<User> records = result.getRecords(); // 当前页数据
long total = result.getTotal(); // 总条数
long pages = result.getPages(); // 总页数

自定义业务方法

在继承 IService 后,可在自定义 Service 接口实现类中扩展业务方法:

接口定义

public interface UserService extends IService<User> {
    // 自定义:根据姓名查询用户
    List<User> getByName(String name);
}

实现类实现

@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public List<User> getByName(String name) {
        return this.baseMapper.selectList(Wrappers.<User>lambdaQuery().eq(User::getName, name));
    }
}

注:ServiceImpl 中已注入 baseMapper(即对应 Mapper),可直接调用原生 Mapper 方法。


高级用法

Lambda 条件构造器

IService 完美支持 Lambda 条件构造器,避免字段名硬编码,推荐使用:

// Lambda查询
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
wrapper.eq(User::getAge, 20)
       .like(User::getEmail, "@qq.com")
       .orderByDesc(User::getId);

List<User> userList = userService.list(wrapper);