详细讲解MybatisPlus中的BaseMapper类中的CRUD功能(全)

目录

  • 前言
  • 1. 基本概念
  • 2. CRUD
    • 2.1 插入
    • 2.2 删除
    • 2.3 修改
    • 2.4 查询

前言

大部分CRUD都来源这个类,对此有意义剖析,方便之后的功能开发

1. 基本概念

MyBatis-Plus(简称MP)是基于 MyBatis 的增强工具,在 MyBatis 的基础上提供了更多的功能和便捷的操作。

基本概念作用功能
一个泛型接口,可以通过泛型指定操作的实体类型1.提供了一组基础的数据库操作方法,包括增、删、改、查等。
2.简化了数据访问层的开发,通过继承 BaseMapper,开发者可以省去很多 CRUD 操作的重复代码。
3.通过 MyBatis-Plus 提供的通用方法,不需要手动编写 XML 映射文件,减少了配置的复杂性。
4.支持 Lambda 表达式查询,提供了更加灵活和强大的查询方式。
1.通用的 CRUD 操作: 提供了基本的增、删、改、查方法,包括插入数据、根据主键查询、根据条件查询、更新数据和删除数据等。
2.分页查询: 支持分页查询,方便处理大量数据时的分页显示。
3.条件构造器: 提供了 QueryWrapper、UpdateWrapper 等条件构造器,方便构建复杂的查询条件。
4.Lambda 表达式查询: 支持使用 Lambda 表达式进行查询,使得查询条件更加类型安全、直观。
5.逻辑删除: 支持逻辑删除,通过标记删除而不是物理删除,提高了数据安全性。
6.乐观锁: 支持乐观锁机制,用于处理并发更新时的数据一致性。
7.自动填充: 支持自动填充功能,自动填充创建时间、更新时间等字段。
8.序列主键生成: 支持序列主键的生成,方便处理主键自增的数据库。

基本的示例代码如下:

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

public interface UserMapper extends BaseMapper<User> {
    // 无需手动编写 SQL,通过继承 BaseMapper 即可使用通用的 CRUD 方法
    // 可以直接使用 Lambda 表达式进行查询,例如:selectList(lambdaQueryWrapper);
    
    // 分页查询
    Page<User> selectPage(Page<User> page);
}

通过继承 BaseMapper 接口,开发者可以直接使用其中定义的通用方法,而无需手动编写大量的重复代码,从而提高开发效率。

对应的源码如下:

/**
 * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
 * <p>这个 Mapper 支持 id 泛型</p>
 *
 * @author hubin
 * @since 2016-01-23
 */
public interface BaseMapper<T> extends Mapper<T> {

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

    /**
     * 根据 ID 删除
     *
     * @param id 主键ID
     */
    int deleteById(Serializable id);

    /**
     * 根据 columnMap 条件,删除记录
     *
     * @param columnMap 表字段 map 对象
     */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根据 entity 条件,删除记录
     *
     * @param wrapper 实体对象封装操作类(可以为 null)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);

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

    /**
     * 根据 ID 修改
     *
     * @param entity 实体对象
     */
    int updateById(@Param(Constants.ENTITY) T entity);

    /**
     * 根据 whereEntity 条件,更新记录
     *
     * @param entity        实体对象 (set 条件值,可以为 null)
     * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    T selectById(Serializable id);

    /**
     * 查询(根据ID 批量查询)
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * 查询(根据 columnMap 条件)
     *
     * @param columnMap 表字段 map 对象
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根据 entity 条件,查询一条记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     * <p>注意: 只返回第一个字段的值</p>
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

2. CRUD

初始的搭建项目可看这篇文章:Springboot整合MybatisPlus的基本CRUD

2.1 插入

新增功能函数整体如下:

函数大致描述
int insert(T entity)插入一条记录

补充一条根据ID主键查询:T selectById(Serializable id)

代码示例如下:

    @Test
    public void test1(){
        User user = new User();
        user.setUsername("ceshi");
        user.setPassword("test");
        int insert = userMapper.insert(user);
        // 此行输出的是 受影响的行数
        System.out.println(insert);

        int id = user.getId();
        user = userMapper.selectById(id);
        System.out.println(user);

    }

截图如下:

在这里插入图片描述

2.2 删除

删除功能函数如下:

函数大致描述
int deleteById(Serializable id)根据 ID 删除
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);根据 columnMap 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper)根据 entity 条件,删除记录。@param wrapper 实体对象封装操作类(可以为 null)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList)删除(根据ID 批量删除),idList 主键ID列表(不能为 null 以及 empty)

为了更好的演示功能函数,对应的数据库表格如下:

在这里插入图片描述

常用的代码如下:

    @Test
    public void test2(){
        /*
        * 删除单行,
        * */
        int delete1 = userMapper.deleteById(6);
        // 删除了多少行
        System.out.println(delete1);


        /*
        * 批量删除,删除第4和第5行
        * */
        List <Integer> idlist = Arrays.asList(4,5);
        int delete2 = userMapper.deleteBatchIds(idlist);
        // 删除了多少行
        System.out.println(delete2);

        /*
        * 删除map字段值,注意此处的Map类型是<String,Object>,而不是自身两个属性的值
         * */
        Map<String,Object> map =new HashMap<>();
        map.put("username","map_username");
        map.put("password","map_password");
        int delete3 = userMapper.deleteByMap(map);
        // 删除了多少行
        System.out.println(delete3);

        QueryWrapper<User> wrapper = new QueryWrapper<User>();
        wrapper.eq("username","ceshi");
        int delete4 = userMapper.delete(wrapper);
        // 删除了多少行
        System.out.println(delete4);
    }

对于以上代码,其中的QueryWrapper类,可看我之前的文章:Mybatis-plus动态条件查询QueryWrapper的函数用法

截图如下所示:

在这里插入图片描述

对应的数据库最后只剩下:

在这里插入图片描述

2.3 修改

修改功能函数如下:

函数大致描述
int updateById(@Param(Constants.ENTITY) T entity)根据 ID 修改
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper)根据 whereEntity 条件,更新记录。entity 实体对象 (set 条件值,可以为 null),updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)

原本的表如下:
在这里插入图片描述

示例代码如下:

    @Test
    public void test3(){
        // 原本第一行是manong
        User user = userMapper.selectById(1);
        System.out.println(user);

        //对user进行修改
        user.setUsername("user1");
        user.setPassword("pass1");
        int update1 = userMapper.updateById(user);
        System.out.println(update1);


        user = userMapper.selectById(2);
        user.setPassword("pass2");
        QueryWrapper wrapper = new QueryWrapper();
        // 此处可以通过like,对搜出来的大部分进行批量修改!
        wrapper.eq("username","yanjiuseng");
        int update2 = userMapper.update(user,wrapper);
        System.out.println(update2);
    }

最后的表如下:

在这里插入图片描述

2.4 查询

查询功能函数如下:

函数大致描述
T selectById(Serializable id)根据 ID 查询。id 主键ID
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList)查询(根据ID 批量查询)。idList 主键ID列表(不能为 null 以及 empty)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap)查询(根据 columnMap 条件)
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper)根据 entity 条件,查询一条记录。queryWrapper 实体对象封装操作类(可以为 null)
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper)根据 Wrapper 条件,查询总记录数。queryWrapper 实体对象封装操作类(可以为 null)
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper)根据 entity 条件,查询全部记录。queryWrapper 实体对象封装操作类(可以为 null)
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper)根据 Wrapper 条件,查询全部记录。queryWrapper 实体对象封装操作类(可以为 null)
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper)根据 Wrapper 条件,查询全部记录。只返回第一个字段的值
<E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper)根据 entity 条件,查询全部记录(并翻页)。queryWrapper 实体对象封装操作类(可以为 null)
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper)根据 Wrapper 条件,查询全部记录(并翻页)

为了更好的凸显上述函数的使用,将表中的数据改为如下:

在这里插入图片描述

示例代码如下:

    @Test
    public void test4(){
        //根据id主键查询数据
        User user = userMapper.selectById(1);
        System.out.println("根据id主键查询数据:");
        System.out.println(user);

        //根据querywrapper查询
        user = userMapper.selectOne(new QueryWrapper<User>().eq("username","yanjiuseng"));
        System.out.println("根据querywrapper查询:");
        System.out.println(user);
        //另外一种方式,根据 LambdaQueryWrapper 的条件查询
        user = userMapper.selectOne(new LambdaQueryWrapper<User>().like(User::getUsername,"yanjiuseng"));
        System.out.println("根据 LambdaQueryWrapper 的条件查询:");
        System.out.println(user);

        //根据id主键批量查询
        List<Integer> list = Arrays.asList(3,4,5);
        List<User> users = userMapper.selectBatchIds(list);
        System.out.println("根据id主键批量查询:");
        users.forEach(System.out::println);

        //通过map条件查询
        Map<String,Object> map = new HashMap<>();
        map.put("username","user6");
        users = userMapper.selectByMap(map);
        System.out.println("通过map条件查询:");
        users.forEach(System.out::println);

        //查询所有值
        users = userMapper.selectList(null);
        System.out.println("查询所有值:");
        users.forEach(System.out::println);
    }

终端输出如下所示:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/285072.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图像分割实战-系列教程8:unet医学细胞分割实战6(医学数据集、图像分割、语义分割、unet网络、代码逐行解读)

&#x1f341;&#x1f341;&#x1f341;图像分割实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 unet医学细胞分割实战1 unet医学细胞分割实战2 unet医学细胞分割实战3 unet医学细胞分割实战4 unet…

学习体系结构 - Arm 通用中断控制器 v3 和 v4

学习体系结构 - Arm 通用中断控制器 v3 和 v4 Learn the architecture - Arm Generic Interrupt Controller v3 and v4 Version 3.2 借助DeepL翻译 个人补充一些内容 建议提前阅读&#xff1a; arm 的 异常模型 1、Overview 本指南概述了 Arm 通用中断控制器 (GIC) v3 和 v4 …

Python算法例32 统计数字

1. 问题描述 计算数字k在0~n中出现的次数&#xff0c;k可能是0~9中的一个数字。 2. 问题示例 n12&#xff0c;k1&#xff0c;在[0&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;6&#xff0c;7&#xff0c;8&#xff0c;9&#xff0c;10&a…

BGP路由知识点

目录 1.BGP的工作原理&#xff1a; 2.BGP路由的一般格式&#xff1a; 3.三种不同的自治系统AS 4.BGP的路由选择 5.BGP的四种报文 BGP&#xff08;Border Gateway Protocol&#xff09;是一种用于自治系统&#xff08;AS&#xff09;之间的路由选择协议。它是互联网中最常用…

2023年12月编程语言排行榜

TIOBE Index for December 2023 December Headline: C# on its way to become programming language of the year 2023 2023年12月的TIOBE指数&#xff1a;12月头条:c#将成为2023年最佳编程语言 Yes, I know, we have been here before. At the end of 2022, it looked like …

项目经验简单总结

引擎 unity 2020 语言 C# lua python(用于工具链) java (用于SDK对接) js&#xff08;PC WEB SDK对接&#xff09; 编辑器 VS VSCODE IDEA eclipse 项目开发模块规划分 主项目工程&#xff0c;UI资源项目工程&#xff0c;模型场景资源项目工程 主项目工程&#xff1a;所有的…

国标GB28181对接的时候如何配置服务端口和本地端口

目 录 一、国标GB28181对接需要配置的端口等参数 二、GB28181服务器端口的配置&#xff1a;SIP服务器端口 三、GB28181设备测端口的配置&#xff1a;本地SIP端口 &#xff08;一&#xff09;本地SIP端口配置的意义 &#xff08;二&#xf…

Spring Cloud + Vue前后端分离-第9章 大文件断点续与极速秒传

源代码在GitHub - 629y/course: Spring Cloud Vue前后端分离-在线课程 ​​​​​​Spring Cloud Vue前后端分离-第9章 大文件断点续与极速秒传 作为一个视频网站&#xff0c;一个文件小则几十M&#xff0c;大则上G&#xff0c;上传一个大文件受网络影响很大&#xff0c;文…

Linux--批量自动装机

实验环境 随着某公司业务不断发展&#xff0c;服务器主机的数量也迅速增长&#xff0c;对于功能变更或新采购的服务器&#xff0c; 需要重新安装CentOS7操作系统&#xff0c;为了提高服务器装机效率&#xff0c;要求基于PXE网络实现全自动无人值 守批量安装。 需求描述 > 服…

【面向对象项目之图书馆管理系统】

项目需求 不同的用户有不同的菜单&#xff0c;然后进行操作。 设计思路 通过需求我们可以提取图书类&#xff0c;书架类 图书类存放图书的基本信息&#xff0c;书架类存放书本及其它的数量&#xff0c;以及操作图书的方法等等。接口类&#xff08;用来操作书架里面的图书&…

2023年“中银杯”安徽省网络安全B模块(部分解析)

前言 以下是2023年中银杯安徽省网络安全B模块题目&#xff0c;镜像可以私聊我 B模块安全事件响应/网络安全数据取证/应用安全&#xff08;400 分&#xff09; B-1&#xff1a;CMS网站渗透测试 任务环境说明&#xff1a; √服务器场景&#xff1a;Server2206&#xff08;关…

虚幻UE 材质-PDO像素深度偏移量

2024年的第一天&#xff01;&#xff01;&#xff01;大家新年快乐&#xff01;&#xff01;&#xff01; 可能是长大了才知道 当你过得一般 你的亲朋好友对你真正态度只可能是没有表露出来的冷嘲热讽了 希望大家新的一年平安、幸福、 永远活力满满地追求自己所想做的、爱做的&…

计算图与动态图机制

一、计算图 计算图是用来描述运算的有向无环图 计算图有两个主要元素&#xff1a;结点&#xff08;Node&#xff09;和边&#xff08;Edge&#xff09; 结点表示数据&#xff0c;如向量&#xff0c;矩阵&#xff0c;张量边表示运算&#xff0c;如加减乘除卷积等 用计算图表…

nginx源码分析-4

这一章内容讲述nginx的模块化。 ngx_module_t&#xff1a;一个结构体&#xff0c;用于描述nginx中的各个模块&#xff0c;其中包括核心模块、HTTP模块、事件模块等。这个结构体包含了一些模块的关键信息和回调函数&#xff0c;以便nginx在运行时能够正确地加载和管理这些模块。…

【话题】ChatGPT等大语言模型为什么没有智能2

我们接着上一次的讨论&#xff0c;继续探索大模型的存在的问题。正巧CSDN最近在搞文章活动&#xff0c;我们来看看大模型“幻觉”。当然&#xff0c;本文可能有很多我自己的“幻觉”&#xff0c;欢迎批评指正。如果这么说的话&#xff0c;其实很容易得出一个小结论——大模型如…

【Linux】socket基础API

目录 1. 创建socket&#xff08;TCP/UDP&#xff0c;客户端服务器&#xff09; 1.1 第一个参数——domain 1.2 第二个参数——type 1.3 第三个参数——protocol 2. 绑定socket地址&#xff08;TCP/UDP&#xff0c;服务器&#xff09; 2.1 字节序及转换函数 2.2 IP地址及…

听GPT 讲Rust源代码--library/proc_macro

File: rust/library/proc_macro/src/bridge/rpc.rs 在Rust源代码中&#xff0c;rust/library/proc_macro/src/bridge/rpc.rs文件的作用是实现了Rust编程语言的编译过程中的远程过程调用&#xff08;RPC&#xff09;机制。 这个文件定义了与编译器的交互过程中使用的各种数据结构…

bilibili深入理解计算机系统笔记(3):使用C语言实现静态链接器

本文是2022年的项目笔记&#xff0c;2024年1月1日整理文件的时候发现之&#xff0c;还是决定发布出来。 Github链接&#xff1a;https://github.com/shizhengLi/csapp_bilibili 文章目录 可执行链接文件(ELF)ELF headerSection header符号表symtab二进制数如何和symtab结构成员…

OpenCV-Python(29):图像特征

目录 目标 背景介绍 常用特征 应用场景 目标 理解什么是图像特征 为什么图像特征很重要 为什么角点很重要 背景介绍 相信大多数人都玩过拼图游戏吧。首先你们拿到一张图片的一堆碎片&#xff0c;你要做的就是把这些碎片以正确的方式排列起来从而重建这幅图像。问题是&…

【并发设计模式】聊聊Thread-Per-Message与Worker-Thread模式

在并发编程中&#xff0c;核心就是同步、互斥、分工。 同步是多个线程之间按照一定的顺序进行执行&#xff0c;比如A执行完&#xff0c;B在执行。而互斥是多个线程之间对于共享资源的互斥。两个侧重点不一样&#xff0c;同步关注的是执行顺序&#xff0c;互斥关注的是资源的排…