三、基本 CRUD

22 阅读3分钟

内容核心围绕 BaseMapper通用 Service(IService/ServiceImpl)


1. 你要先搞清楚:MP 的 CRUD 是怎么来的?

MyBatis-Plus(MP)把单表常用 CRUD 都封装进了 BaseMapper(Mapper 层)以及 IService / ServiceImpl(Service 层)。所以你只要:

  1. 写好实体类 User
  2. 写一个 UserMapper extends BaseMapper<User>
    就能直接 insert/delete/update/select 了。

2. Mapper 层:BaseMapper(必会)

2.1 BaseMapper 里有哪些“最常用”的 CRUD 方法?

典型方法:insertdeleteByIddeleteByMapdeleteBatchIdsupdateByIdselectByIdselectBatchIdsselectByMapselectListselectCount 等。

你可以把它记成一张“心智地图”:

  • 新增insert(entity)

    • 按 id:deleteById(id)
    • 批量 id:deleteBatchIds(list)
    • 按条件 map:deleteByMap(map)
    • 按 wrapper:delete(wrapper)
    • 按 id:updateById(entity)
    • 按条件:update(entity, updateWrapper)
    • 按 id:selectById(id)
    • 批量 id:selectBatchIds(list)
    • 按条件 map:selectByMap(map)
    • 查所有/按条件:selectList(wrapper)(wrapper=null 就是全表)

3. 基本 CRUD:每一种都给你“最短可跑通”的例子

3.1 插入 insert

@Test
public void testInsert(){
    User user = new User(null, "张三", 23, "zhangsan@atguigu.com");
    int result = userMapper.insert(user);
    System.out.println("受影响行数:"+result);
    System.out.println("id自动获取:"+user.getId());
}

资料说明:插入时 MP 默认用雪花算法生成 id(你会看到插入后 user.getId() 有值)。

学习要点

  • 如果你的表主键是自增,别忘了配置主键策略(后面会学到 IdType.AUTO)。
  • 插入后主键回填:user.getId() 是常考点。

3.2 删除 delete

(1) 根据 id 删除

@Test
public void testDeleteById(){
    int result = userMapper.deleteById(1475754982694199298L);
    System.out.println("受影响行数:"+result);
}

(2) 批量 id 删除

@Test
public void testDeleteBatchIds(){
    List<Long> idList = Arrays.asList(1L, 2L, 3L);
    int result = userMapper.deleteBatchIds(idList);
    System.out.println("受影响行数:"+result);
}

(3) 通过 map 条件删除

@Test
public void testDeleteByMap(){
    Map<String, Object> map = new HashMap<>();
    map.put("age", 23);
    map.put("name", "张三");
    int result = userMapper.deleteByMap(map);
    System.out.println("受影响行数:"+result);
}

学习要点

  • deleteByMap等值 AND 条件(map 里的字段会拼成 name=? AND age=?)。
  • 想要更复杂条件(like、between、or),要学 Wrapper(在后续章节)。

3.3 修改 update

根据 id 修改

@Test
public void testUpdateById(){
    User user = new User(4L, "admin", 22, null);
    int result = userMapper.updateById(user);
    System.out.println("受影响行数:"+result);
}

学习要点(很关键)

  • 你这里 email=null:在 MP 里是否会更新为 NULL,取决于 字段更新策略(默认策略与配置有关)。初学阶段先记住:更新时尽量只给你要改的字段赋值,避免误伤。
  • 复杂条件更新用 update(entity, updateWrapper)(后面章节会练)。

3.4 查询 select

(1) 根据 id 查询

@Test
public void testSelectById(){
    User user = userMapper.selectById(4L);
    System.out.println(user);
}

(2) 多个 id 批量查询

@Test
public void testSelectBatchIds(){
    List<Long> idList = Arrays.asList(4L, 5L);
    List<User> list = userMapper.selectBatchIds(idList);
    list.forEach(System.out::println);
}

(3) map 条件查询

@Test
public void testSelectByMap(){
    Map<String, Object> map = new HashMap<>();
    map.put("age", 22);
    map.put("name", "admin");
    List<User> list = userMapper.selectByMap(map);
    list.forEach(System.out::println);
}

(4) 查询所有

@Test
public void testSelectList(){
    List<User> list = userMapper.selectList(null);
    list.forEach(System.out::println);
}

selectList(null)null 表示不加条件,即全表查询。


4. Service 层:通用 Service(IService / ServiceImpl)

通用 Service 在 Mapper 的基础上又封装了一层,更贴近业务习惯(get/list/page/remove 等命名)。

4.1 创建方式(核心就两步)

(1) 接口继承 IService

public interface UserService extends IService<User> {
}

(2) 实现类继承 ServiceImpl

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

4.2 Service 层常用示例

统计总数

@Test
public void testGetCount(){
    long count = userService.count();
    System.out.println("总记录数:" + count);
}

批量插入(saveBatch)

@Test
public void testSaveBatch(){
    ArrayList<User> users = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        User user = new User();
        user.setName("ybc" + i);
        user.setAge(20 + i);
        users.add(user);
    }
    userService.saveBatch(users);
}

批量插入放在 Service 层做,是因为 SQL 长度限制等原因。


5. 一套最有效的练习路线(照着做就会)

练习 A:BaseMapper CRUD(必须全写)

  1. insert:插入 1 条,打印回填 id
  2. deleteById:删掉刚插入的
  3. deleteBatchIds:删 1,2,3
  4. updateById:改 id=4 的 name、age
  5. selectById / selectBatchIds / selectByMap / selectList(null) 全跑通

练习 B:Service CRUD(体会封装)

  1. userService.count()
  2. userService.saveBatch() 批量插 5 条
  3. 对比 Mapper 层批量插入为什么不方便(理解“SQL长度有限制”)

6. 常见坑(学 CRUD 时最容易卡的点)

  • 表名/实体名不一致:MP 默认“实体类名≈表名”,不一致要用 @TableName 或全局前缀配置
  • 主键不是 id:表里主键叫 uid 之类,需要 @TableId 指定,否则插入会报“没有默认值/Unknown column”等问题(后面注解章节会系统讲)。
  • selectList(null)null 真的是“无条件”,别误以为是“查不到”。