Mybatis-Plus中Service層和Mapper層提供的常見方法有哪些?
一、Mapper 層:BaseMapper<T> 接口
這是最底層、最接近數據庫的一層。只要你的 UserMapper 接口繼承了 BaseMapper<User>,它就自動擁有了以下所有方法。這些方法是所有上層方法的基礎。
核心特點:
- 面向數據:方法名都是動詞+名詞的形式,如
selectById,insert,非常直觀。 - 參數直接:參數通常是實體
T、主鍵Serializable或Wrapper。 - 返回直接:返回值是影響的行數
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 等是其獨有的亮點。 |
總結與最佳實踐
-
在
Service實現類 (UserServiceImpl) 內部,你應該優先使用Service層自身提供的方法。例如,用this.getById()而不是baseMapper.selectById(),用this.saveBatch()而不是自己去循環調用baseMapper.insert()。因為ServiceImpl提供了更好的封裝和增強功能。 -
BaseMapper是ServiceImpl的基礎。ServiceImpl內部所有對數據庫的操作,最終都是委托給它注入的baseMapper來完成的。 -
當需要編寫自定義 SQL 時,方法應該定義在
Mapper接口 (UserMapper) 中,然后在Service層通過注入的userMapper實例來調用。
這個分層設計非常清晰:Controller -> Service -> Mapper。
Controller調用Service的業務方法。Service實現業務邏輯,優先使用IService提供的便捷方法(內部調用Mapper),如果功能不足,再直接調用Mapper的方法(包括自定義的 SQL 方法)。Mapper負責最終的數據庫交互。

浙公網安備 33010602011771號