//打赏的js文件

Mybatis-Plus中Service层和Mapper层提供的常见方法有哪些?

一、Mapper 层:BaseMapper<T> 接口

这是最底层、最接近数据库的一层。只要你的 UserMapper 接口继承了 BaseMapper<User>,它就自动拥有了以下所有方法。这些方法是所有上层方法的基础。

核心特点:

  • 面向数据:方法名都是动词+名词的形式,如 selectById, insert,非常直观。
  • 参数直接:参数通常是实体 T、主键 SerializableWrapper
  • 返回直接:返回值是影响的行数 int、实体 T 或列表 List<T>

常用方法列表:

【插入】

  • insert(T entity): 插入一条记录。

【删除】

  • deleteById(Serializable id): 根据主键删除。
  • deleteByMap(Map<String, Object> columnMap): 根据 Map 条件删除。
  • deleteBatchIds(Collection<? extends Serializable> idList): 批量删除。
  • delete(Wrapper<T> wrapper): 根据条件构造器删除。

【修改】

  • updateById(T entity): 根据主键更新(只更新非 null 字段)。
  • update(T entity, Wrapper<T> updateWrapper): 根据条件构造器更新。

【查询】

  • selectById(Serializable id): 根据主键查询。
  • selectBatchIds(Collection<? extends Serializable> idList): 批量查询。
  • selectByMap(Map<String, Object> columnMap): 根据 Map 条件查询。
  • selectOne(Wrapper<T> wrapper): 查询一条记录(结果多于1条会报错)。
  • selectCount(Wrapper<T> wrapper): 查询总记录数。
  • selectList(Wrapper<T> wrapper): (极其常用) 查询列表。
  • selectMaps(Wrapper<T> wrapper): 查询列表,结果是 List<Map>
  • selectObjs(Wrapper<T> wrapper): 查询列表,只返回第一列的值。

【分页查询】

  • selectPage(IPage<T> page, Wrapper<T> wrapper): (极其常用) 分页查询。
  • selectMapsPage(IPage<Map<String, Object>> page, Wrapper<T> wrapper): 分页查询,结果是 List<Map>

二、Service 层:IService<T> 接口 & ServiceImpl<M, T> 实现类

Service 层是面向业务的一层。它封装了对 Mapper 层的调用,并提供了一些更方便、更业务化的方法。你的 UserService 接口通常会继承 IService<User>,而实现类 UserServiceImpl 会继承 ServiceImpl<UserMapper, User>

核心特点:

  • 面向业务:方法名更贴近业务操作,如 save, remove, list
  • 封装逻辑:对 Mapper 的调用进行了封装,比如将 insert > 0 的判断封装在 save 方法中,直接返回 boolean
  • 功能增强:提供了一些 Mapper 层没有的便捷方法,特别是批量操作

常用方法列表:

【单个操作 (基本是对 Mapper 的封装)】

  • save(T entity): 保存一条记录。内部调用 mapper.insert(),返回 boolean
  • removeById(Serializable id): 根据主键删除。返回 boolean
  • updateById(T entity): 根据主'键更新。返回 boolean
  • getById(Serializable id): 根据主键查询。
  • getOne(Wrapper<T> queryWrapper, boolean throwEx): 查询一条记录。throwEx 参数可以控制当结果不唯一时是否抛出异常。
  • count() / count(Wrapper<T> queryWrapper): 查询总数。
  • list() / list(Wrapper<T> queryWrapper): 查询列表。
  • page(IPage<T> page, Wrapper<T> queryWrapper): 分页查询。

【批量操作 (Service 层的增强亮点!)】
这些方法在 BaseMapper 中是没有的,ServiceImpl 内部通过循环或批处理的方式实现,非常方便。

  • saveBatch(Collection<T> entityList): 批量插入。
  • saveOrUpdateBatch(Collection<T> entityList): 批量插入或更新(根据主键是否存在)。
  • removeByIds(Collection<? extends Serializable> idList): 批量删除。
  • updateBatchById(Collection<T> entityList): 批量更新。

【插入或更新】

  • saveOrUpdate(T entity): 根据实体的主键是否存在,自动判断是执行 insert 还是 update。在表单提交等场景中非常有用。

三、Mapper 层 vs Service 层:一张对比图

对比维度 BaseMapper (Mapper 层) IService / ServiceImpl (Service 层)
定位 数据访问层 (DAO),直接与数据库交互。 业务逻辑层,封装和编排业务,调用 Mapper。
方法命名 数据操作导向 (e.g., selectById, insert) 业务操作导向 (e.g., getById, save)
返回值 更原始,如返回影响行数 int 更友好,如将 int > 0 转换为 boolean
核心能力 提供所有基础的、原子的数据库 CRUD 操作。 在 Mapper 基础上,封装了常用逻辑,并提供了强大的批量操作
典型调用 userMapper.selectById(1L); userService.getById(1L);
Wrapper 用法 userMapper.selectList(wrapper); userService.list(wrapper);
特色功能 分页查询 selectPage 是其核心功能之一。 批量操作 saveBatch, removeByIds 等是其独有的亮点。

总结与最佳实践

  1. Service 实现类 (UserServiceImpl) 内部,你应该优先使用 Service 层自身提供的方法。例如,用 this.getById() 而不是 baseMapper.selectById(),用 this.saveBatch() 而不是自己去循环调用 baseMapper.insert()。因为 ServiceImpl 提供了更好的封装和增强功能。

  2. BaseMapperServiceImpl 的基础ServiceImpl 内部所有对数据库的操作,最终都是委托给它注入的 baseMapper 来完成的。

  3. 当需要编写自定义 SQL 时,方法应该定义在 Mapper 接口 (UserMapper) 中,然后在 Service 层通过注入的 userMapper 实例来调用。

这个分层设计非常清晰:Controller -> Service -> Mapper

  • Controller 调用 Service 的业务方法。
  • Service 实现业务逻辑,优先使用 IService 提供的便捷方法(内部调用 Mapper),如果功能不足,再直接调用 Mapper 的方法(包括自定义的 SQL 方法)。
  • Mapper 负责最终的数据库交互。
posted @ 2025-06-28 10:44  星陨光逝  阅读(439)  评论(0)    收藏  举报