MyBatis-Plus(简称 MP)在原生 MyBatis 基础上,对Service 层进行了深度封装,提供了通用的 IService 接口和 ServiceImpl 实现类,无需编写重复的 CRUD 模板代码,极大简化了 Service 层开发。
MP 对 Service 层的封装基于两个核心类:
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 接口继承 MP BaseMapper<T>:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}自定义业务接口继承 IService<T>,即可直接使用 MP 提供的所有通用方法:
import com.baomidou.mybatisplus.extension.service.IService;
public interface UserService extends IService<User> {
// 此处可扩展自定义业务方法
}实现类继承 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能力
// 自定义业务方法在此实现
}核心优势:只需继承对应接口 / 实现类,无需编写
save、list、page等基础方法,直接调用即可。
IService 封装了单条 / 批量 CRUD、分页、条件查询、计数等常用操作,按功能分类如下:
// 单条新增
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);// 根据ID删除
userService.removeById(1L);
// 条件删除:删除年龄大于30的用户
userService.remove(Wrappers.<User>lambdaQuery().gt(User::getAge, 30));// 根据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, "张三"));// 根据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, "李"));MP 集成分页插件,IService 直接提供分页方法:
// 前提:配置MyBatis-Plus分页插件
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}分页方法:
// 第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);