BaseMapper——新增和删除

目录

[3 BaseMapper](#3 BaseMapper)

[3.1 新增](#3.1 新增)

[3.2 删除](#3.2 删除)

[根据 ID 删除](#根据 ID 删除)

根据实体id删除

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

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


3 BaseMapper

MyBatis-Plus中的基本CRUD在内置的BaseMapper中都已得到了实现,我们可以直接使用。

只需要用自己的Mapper继承BaseMapper。<>里的值是实体类。

复制代码
package com.qcby.mybatisplus1122.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qcby.mybatisplus1122.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
//@Repository
public interface UserMapper extends BaseMapper<User> {

}

BaseMapper里的方法如下:

3.1 新增

复制代码
/**
 * 插入一条记录
 *
 * @param entity 实体对象
 */
int insert(T entity);

@Test
public void testInsert(){
    User user = new User(null, "张三", 23, "zhangsan@qcby.com",0);
    //INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
    int result = userMapper.insert(user);
    System.out.println("受影响行数:"+result);
    System.out.println("id自动获取:"+user.getId());
}


注:默认的主键生成策略是自动生成雪花id。创建一个新的 User 对象(new User())并且没有手动设置 id 时,在调用 insert 方法之前,MyBatis-Plus 会自动使用雪花算法为这个 id 字段生成一个唯一的值。然后再进行插入。此时,数据库表的 AUTO_INCREMENT 设置会被忽略。因为 SQL 插入语句中已经明确指定了 id 的值,数据库会优先使用你提供的值,而不会再自动生成一个。除非配置主键生成策略为 @TableId(type = IdType.AUTO),即由数据库来生成 ID。

3.2 删除

  1. 根据id删除
根据 ID 删除
复制代码
/**
 * 根据 ID 删除
 *
 * @param id 主键ID
 */
int deleteById(Serializable id);

入参类型为Serializable,具体解释如下:
Serializable 是什么

  • Serializable 是 Java 中的一个接口,它是一个 标记接口(Marker Interface),没有任何方法。一个类只要实现了 Serializable 接口,就表示它的对象可以被 "序列化",即可以被转换为字节流,用于网络传输或持久化存储。(具体见++8 MyBatis缓存++ 8.5 序列化和Serializable接口)

  • 更重要的是,Java 中所有的 基本类型包装类(如 Integer, Long, String, Byte 等)都实现了 Serializable 接口。
    为什么要用 Serializable 作为参数类型

  • MyBatis-Plus 的 BaseMapper 是一个通用的接口,它需要适配各种不同类型的主键。数据库中的主键(Primary Key)可以是:

    • 自增的整数 (INT 或 BIGINT),对应 Java 的 Integer 或 Long。
    • 字符串 (VARCHAR),例如用 UUID 作为主键,对应 Java 的 String。
    • 复合主键(由多个字段组成),这时候通常会用一个自定义的 Java 对象来表示,这个对象也需要实现 Serializable。
  • 如果 deleteById 方法的参数类型被固定为 long,那么它就无法处理 String 类型或其他类型的主键,框架的通用性就会大打折扣。

  • 通过将参数类型定义为 Serializable,deleteById 方法就可以接收 任何可以作为主键的、实现了 Serializable 接口的对象 作为参数。这使得 BaseMapper 能够无缝地应用于几乎所有的数据库表,而无需为不同类型的主键编写不同的方法。

    @Test
    public void testDeleteById(){
    //通过id删除用户信息
    //DELETE FROM user WHERE id=?
    int result = userMapper.deleteById(1994336252221046788l);
    System.out.println("受影响行数:"+result);
    }

注:第5行的入参id加L是因为:

  • 如果不加l,直接写数字,比如 1992070154670944258 ,Java 编译器会默认将其解析为 int 类型。
  • 然而,int 类型有其最大值限制,这个值是 2,147,483,647 (大约 21 亿)。
  • 生成的雪花 ID 1992070154670944258 远远超过了 int 的最大值,这会导致 整数溢出。编译器会报错,提示你这个数字太大,无法用 int 表示。
  • 所以加l是为了让 Java 编译器能正确地将这个巨大的数字识别为 long 类型,而不是因为 MyBatis-Plus 有什么特殊要求。
根据实体id删除
复制代码
/**
 * 根据实体(ID)删除
 *
 * @param entity 实体对象
 * @since 3.4.4
 */
int deleteById(T entity);

@Test
public void testDeleteById1(){
    //通过id删除用户信息
    //DELETE FROM user WHERE id=?
    User user = new User();
    user.setId(1992507084072103937l);
    int result = userMapper.deleteById(user);
    System.out.println("受影响行数:"+result);
}
  1. 根据条件删除
根据 columnMap 条件删除
复制代码
/**
 * 根据 columnMap 条件,删除记录
 *
 * @param columnMap 表字段 map 对象
 */
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

Test
public void testDeleteByMap(){
    //根据map集合中所设置的条件删除记录
    //DELETE FROM user WHERE name = ? AND age = ?
    Map<String, Object> map = new HashMap<>();
    map.put("age", 23);
    map.put("name", "张三");
    int result = userMapper.deleteByMap(map);
    System.out.println("受影响行数:"+result);
}
根据 queryWrapper 条件删除
复制代码
/**
 * 根据 entity 条件,删除记录
 *
 * @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
 */
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

int:

  • 返回值是一个整数,表示受影响(被删除)的记录数。
    @Param(Constants.WRAPPER):

  • 这是一个 MyBatis 的注解,用来指定传入的参数在 XML 映射文件中的名称。Constants.WRAPPER 的值是 "ew",所以在 XML 里你会看到 #{ew.customSqlSegment} 这样的占位符。
    Wrapper queryWrapper:

  • 这是方法的核心参数。Wrapper 是一个条件构造器接口,QueryWrapper 是它的一个常用实现类,用于构建 WHERE 子句。T 是你的实体类泛型,这里就是 User。

    @Test
    public void testDelete(){
    String name = "abc";
    //QueryWrapper用于构建 WHERE 子句
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //使用 eq 方法(equal 的缩写)添加条件:name = ?
    // 第一个参数是数据库表的字段名(如果实体属性名和字段名一致,可以用属性名)
    // 第二个参数是要匹配的值
    queryWrapper.eq("name", name);

    复制代码
      //DELETE FROM user WHERE name = 'abc';
      int deletedCount = userMapper.delete(queryWrapper);
      System.out.println("成功删除了 " + deletedCount + " 条记录。");

    }

  1. 批量删除

    /**

    • 删除(根据ID或实体 批量删除)
    • @param idList 主键ID列表或实体列表(不能为 null 以及 empty)
      */
      int deleteBatchIds(@Param(Constants.COLLECTION) Collection<?> idList);

    @Test
    public void testDeleteBatchIds(){
    //通过多个id批量删除
    //DELETE FROM user WHERE id IN ( ? , ? , ? )
    List<Long> idList = Arrays.asList(6L, 7L);
    int result = userMapper.deleteBatchIds(idList);
    System.out.println("受影响行数:"+result);
    }

相关推荐
后端AI实验室2 小时前
我让AI模拟面试官考了我一个小时,然后我沉默了
java·ai
金銀銅鐵2 小时前
Byte Buddy 生成的类的结构如何?(第二篇)
java·后端
StackNoOverflow2 小时前
Spring MVC零散知识点记录
java·spring·mvc
几许2 小时前
高并发有序顺序号生成中间件 - 架构设计文档
java·后端
几许2 小时前
高并发强一致性顺序号生成系统 -- SequenceGenerator
java·github
闻哥2 小时前
深入理解 MySQL InnoDB Buffer Pool 的 LRU 冷热数据机制
android·java·jvm·spring boot·mysql·adb·面试
xiangpanf2 小时前
PHP vs C语言:30字解析两大编程语言差异
c语言·开发语言·php
wdfk_prog2 小时前
MAX14830 可移植 C 驱动实现分析:一个适合多串口扩展场景的开源基础版本
c语言·开发语言·开源