IService——删除

目录

[4.3.2 删除](#4.3.2 删除)

普通根据id删除

根据id删除(是否填充)

根据实体id删除

[根据 columnMap 条件删除](#根据 columnMap 条件删除)

[根据 queryWrapper 条件删除](#根据 queryWrapper 条件删除)

根据ID删除(SQL有in)

根据id删除(是否填充)

根据id批量删除(SQL无in)

根据id批量删除(SQL无in,是否填充)

根据id和批次批量删除(SQL无in)

根据id和批次批量删除(SQL无in,是否填充)


4.3.2 删除

  1. 根据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);
}
  1. 根据条件删除
根据 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);
}
  1. 批量删除
根据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);
}
相关推荐
m0_730115112 小时前
C++与Python混合编程实战
开发语言·c++·算法
小罗和阿泽3 小时前
接口测试系列 接口自动化测试 pytest框架(三)
开发语言·python·pytest
guestsun4 小时前
SpringBoot七大事务失效场景分析
java·spring boot·mybatis
毕设源码-邱学长9 小时前
【开题答辩全过程】以 基于Java的学校住宿管理系统的设计与实现为例,包含答辩的问题和答案
java·开发语言
rookieﻬ°10 小时前
PHP框架漏洞
开发语言·php
炸膛坦客11 小时前
单片机/C/C++八股:(二十)指针常量和常量指针
c语言·开发语言·c++
兑生11 小时前
【灵神题单·贪心】1481. 不同整数的最少数目 | 频率排序贪心 | Java
java·开发语言
daidaidaiyu11 小时前
一文学习 Spring 声明式事务源码全流程总结
java·spring
炸膛坦客12 小时前
单片机/C/C++八股:(十九)栈和堆的区别?
c语言·开发语言·c++