目录
[4.3.2 删除](#4.3.2 删除)
[根据 columnMap 条件删除](#根据 columnMap 条件删除)
[根据 queryWrapper 条件删除](#根据 queryWrapper 条件删除)
4.3.2 删除
- 根据id删除
普通根据id删除
/**
* 根据 ID 删除
*
* @param id 主键ID
*/
default boolean removeById(Serializable id) {
return SqlHelper.retBool(getBaseMapper().deleteById(id));
}
@Test
public void removeById(){
Boolean res = userService.removeById(9l);
System.out.println(res);
}

根据id删除(是否填充)
/**
* 根据 ID 删除
*
* @param id 主键(类型必须与实体类型字段保持一致)
* @param useFill 是否启用填充(为true的情况,会将入参转换实体进行delete删除)
* @return 删除结果
* @since 3.5.0
*/
default boolean removeById(Serializable id, boolean useFill) {
throw new UnsupportedOperationException("不支持的方法!");
}
useFill = true 的作用是:
先通过 id 值创建一个你的实体类。然后,在调用 user.setId(8l) 将 ID 设置到这个新创建的 user 对象中。
但在执行删除之前,Mybatis-Plus 会检查这个新创建的 user 对象,并触发 自动填充(AutoFill) 逻辑。
-
如果你在实体类的某些字段上配置了自动填充规则(例如,使用 @TableField(fill = FieldFill.INSERT) 或 FieldFill.UPDATE),这些规则会被执行。
填充完成后,Mybatis-Plus 会使用这个已经填充好的 user 对象作为条件来构建删除语句。这个可以用来实现逻辑删除。@Test
public void removeById1(){
Boolean res = userService.removeById(8l,true);
System.out.println(res);
}

根据实体id删除
/**
* 根据实体(ID)删除
*
* @param entity 实体
* @since 3.4.4
*/
default boolean removeById(T entity) {
return SqlHelper.retBool(getBaseMapper().deleteById(entity));
}
@Test
public void removeById2(){
User user = new User();
user.setId(7l);
Boolean res = userService.removeById(user);
System.out.println(res);
}

- 根据条件删除
根据 columnMap 条件删除
/**
* 根据 columnMap 条件,删除记录
*
* @param columnMap 表字段 map 对象
*/
default boolean removeByMap(Map<String, Object> columnMap) {
Assert.notEmpty(columnMap, "error: columnMap must not be empty");
return SqlHelper.retBool(getBaseMapper().deleteByMap(columnMap));
}
Map columnMap:
-
Key: String 类型,代表数据库表中的列名(或者是 Mybatis 实体类中与列对应的属性名,具体取决于你的配置,比如在实体类中使用了 @TableField 注解来映射不同的数据库列名,那么这里必须使用注解中指定的 value)。
-
Value: Object 类型,代表要匹配的值。可以是任意类型,Mybatis-Plus 会在底层处理类型转换。
return boolean: -
返回一个布尔值,表示删除操作是否成功(通常是指是否有记录被删除)。
注:Map 中的所有键值对在生成的 SQL 中是用 AND 连接的。这意味着,只有当一条记录同时满足 Map 中的所有条件时,才会被删除。@Test
public void removeByMap(){
// 1. 创建一个 Map 对象
Map<String, Object> columnMap = new HashMap<>();
// 2. 向 Map 中添加删除条件
// Key 是数据库列名,Value 是要匹配的值
columnMap.put("name", "王五1");//and
columnMap.put("age", 24);
//DELETE FROM user WHERE name = '王五1' AND age = 24;
boolean res = userService.removeByMap(columnMap);
System.out.println(res);
}

根据 queryWrapper 条件删除
/**
* 根据 entity 条件,删除记录
*
* @param queryWrapper 实体包装类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default boolean remove(Wrapper<T> queryWrapper) {
return SqlHelper.retBool(getBaseMapper().delete(queryWrapper));
}
@Test
public void remove(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id",1992569893489324033l);
Boolean res = userService.remove(queryWrapper);
System.out.println(res);
}

- 批量删除
根据ID删除(SQL有in)
/**
* 删除(根据ID 批量删除)
*
* @param list 主键ID或实体列表
*/
default boolean removeByIds(Collection<?> list) {
if (CollectionUtils.isEmpty(list)) {
return false;
}
return SqlHelper.retBool(getBaseMapper().deleteBatchIds(list));
}
Collection list:
-
一个 Collection 接口的实现类对象,比如 List 或 Set。
-
Key: 集合中的每个元素都代表数据库表中的主键 ID。ID 的类型可以是 Long, Integer, String 等。
return boolean: -
返回一个布尔值,表示删除操作是否成功(即是否有至少一条记录被删除)。
@Test
public void removeByIds(){
List<Long> idsToDelete = new ArrayList<>();
idsToDelete.add(1992570498735788033L);//in
idsToDelete.add(5L);
Boolean res = userService.removeByIds(idsToDelete);
System.out.println(res);
}

注:
- 事务相关标识:
- 输出里的Registering transaction synchronization for SqlSession(注册 SqlSession 的事务同步)、Transaction synchronization committing SqlSession(事务同步提交 SqlSession)、Transaction synchronization deregistering/closing SqlSession(事务同步注销 / 关闭 SqlSession),都是 Spring 事务管理的典型日志 ------ 说明当前操作被 Spring 的事务机制包裹,会保证操作的原子性(要么全成功、要么全回滚)。
- 数据库操作过程:
- 先创建了 SqlSession,由 Spring 管理 JDBC 连接(JDBC Connection ... will be managed by Spring);
- 执行了DELETE FROM user WHERE id IN (?, ?)的 SQL,参数是两个 Long 类型的 ID,最终成功更新了 2 条记录(<== Updates: 2);
- 操作完成后,事务同步提交了 SqlSession,最终释放并关闭了资源。
根据id删除(是否填充)
/**
* 批量删除
*
* @param list 主键ID或实体列表
* @param useFill 是否填充(为true的情况,会将入参转换实体进行delete删除)
* @return 删除结果
* @since 3.5.0
*/
@Transactional(rollbackFor = Exception.class)
default boolean removeByIds(Collection<?> list, boolean useFill) {
if (CollectionUtils.isEmpty(list)) {
return false;
}
if (useFill) {
return removeBatchByIds(list, true);
}
return SqlHelper.retBool(getBaseMapper().deleteBatchIds(list));
}
@Test
public void removeByIds1(){
List<Long> idsToDelete = new ArrayList<>();
idsToDelete.add(7L);//没有in
idsToDelete.add(8L);
Boolean res = userService.removeByIds(idsToDelete,true);
//Boolean res = userService.removeByIds(idsToDelete,false);
System.out.println(res);
}
- 如果true,没有in

当 useFill = true 时,MyBatis-Plus 会把集合中的每个 ID 逐个转换成实体对象,再触发自动填充后执行删除 ------ 这就导致原本的 "批量 IN 删除",变成了对每个 ID 单独执行一次 DELETE FROM user WHERE id=?。上面日志的意思是:SQL 是 DELETE FROM user WHERE id=?,但参数出现了两次(7 和 8),本质是循环执行了两次单条删除 - 如果是false,有in,因为调用removeByIds

根据id批量删除(SQL无in)
/**
* 批量删除(jdbc批量提交)
*
* @param list 主键ID或实体列表(主键ID类型必须与实体类型字段保持一致)
* @return 删除结果
* @since 3.5.0
*/
@Transactional(rollbackFor = Exception.class)
default boolean removeBatchByIds(Collection<?> list) {
return removeBatchByIds(list, DEFAULT_BATCH_SIZE);
}
循环遍历传入的 list,并为每一个 ID 调用一次 removeById(id) 方法。方法上的 @Transactional(rollbackFor = Exception.class) 注解保证了在这个循环中的所有删除操作要么全部成功,要么在发生异常时全部回滚。
@Test
public void removeBatchByIds(){
List<Long> idsToDelete = new ArrayList<>();
idsToDelete.add(7L);//无in
idsToDelete.add(8L);
Boolean res = userService.removeBatchByIds(idsToDelete);
System.out.println(res);
}
这个方法和removeByIds的区别就是这个无in 每次都执行一次。

根据id批量删除(SQL无in,是否填充)
/**
* 批量删除(jdbc批量提交)
*
* @param list 主键ID或实体列表(主键ID类型必须与实体类型字段保持一致)
* @param useFill 是否启用填充(为true的情况,会将入参转换实体进行delete删除)
* @return 删除结果
* @since 3.5.0
*/
@Transactional(rollbackFor = Exception.class)
default boolean removeBatchByIds(Collection<?> list, boolean useFill) {
return removeBatchByIds(list, DEFAULT_BATCH_SIZE, useFill);
}
@Test
public void removeBatchByIds1(){
List<Long> idsToDelete = new ArrayList<>();
idsToDelete.add(7L);//无in
idsToDelete.add(8L);
Boolean res = userService.removeBatchByIds(idsToDelete,true);
System.out.println(res);
}

根据id和批次批量删除(SQL无in)
/**
* 批量删除(jdbc批量提交)
*
* @param list 主键ID或实体列表
* @param batchSize 批次大小
* @return 删除结果
* @since 3.5.0
*/
default boolean removeBatchByIds(Collection<?> list, int batchSize) {
throw new UnsupportedOperationException("不支持的方法!");
}
@Test
public void removeBatchByIds2(){
List<Long> idsToDelete = new ArrayList<>();
idsToDelete.add(7L);//无in
idsToDelete.add(8L);
Boolean res = userService.removeBatchByIds(idsToDelete,1);
System.out.println(res);
}

根据id和批次批量删除(SQL无in,是否填充)
/**
* 批量删除(jdbc批量提交)
*
* @param list 主键ID或实体列表
* @param batchSize 批次大小
* @param useFill 是否启用填充(为true的情况,会将入参转换实体进行delete删除)
* @return 删除结果
* @since 3.5.0
*/
default boolean removeBatchByIds(Collection<?> list, int batchSize, boolean useFill) {
throw new UnsupportedOperationException("不支持的方法!");
}
@Test
public void removeBatchByIds3(){
List<Long> idsToDelete = new ArrayList<>();
idsToDelete.add(7L);//无in
idsToDelete.add(8L);
Boolean res = userService.removeBatchByIds(idsToDelete,1,true);
System.out.println(res);
}
