MyBatis-Plus 为简化开发而生【核心功能】
文章目录
- 一、前言
- 二、快速入门
- 1. 入门案例
- 2. 常见注解
- 3. 常见配置
- 三、核心功能
- 1. 条件构造器
- 2. 自定义 SQL
- 3. Service 接口
- 3.1 基本使用
- 3.2 复杂条件
一、前言
顾名思义,MyBatis-Plus 其实是 MyBatis 的一个加强版,它可以帮助我们快速高效地编写数据库代码。
优点 | Advantages
① 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性;
② 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring;
③ 损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作;
④ 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求;
⑤ 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题;
⑥ 支持自定义全局通用操作:支持全局通用方法注入;
⑦ 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用;
⑧ 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作;
⑨ 内置分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于写基本List查询;
⑩ 内置性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询。

总结:
① 润物无声,只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑;
② 效率至上,只需简单配置,即可快速进行单表 CRUD 操作,从而节省大量时间;
③ 丰富功能,代码生成、自动分页、逻辑删除、自动填充等功能一应俱全。
二、快速入门
1. 入门案例
如图这是一个基础的 mybatis 项目,它需要编写大量的单表 CRUD 语句,接下来我们将用 MyBatis-Plus 来对代码进行改造。

① 引入依赖
MyBatis-Plus 官方提供了 starter 依赖,其中集成了 MyBatis 和 MyBatis-Plus 的所有功能,并且实现了自动装配效果。 因此我们写了 MyBatis-Plus 的依赖之后,就可以把 MyBatis 的依赖删掉了。
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency>
② 继承 BaseMapper 接口
让自定义的 Mapper 继承 MyBatis-Plus 提供的 BaseMapper 接口,所有的增删改查方法都已经在 BaseMapper 里定义好了。
尖括号里指明泛型为要操作的实体类的类型!

③ 直接使用
Mapper 里不需要再自己写方法,xml 里也不需要自己写 CRUD 语句,外部直接调用 BaseMapper 的增删改查方法即可。

④ 运行成功

BaseMapper 中的方法:查询 select 开头,新增 insert 开头,删除 delete 开头,修改 update 开头!
2. 常见注解
MyBatis-Plus 是如何找到对应的数据表的?
MyBatis-Plus 通过扫描实体类,并基于反射来获取实体类信息作为数据库表信息。
注意:
① MyBatis-Plus 根据泛型类型找到对应的实体类;
② 类名驼峰转下划线,作为数据库的表名;
③ 名为 id 的字段作为数据表的主键;
④ 变量名驼峰转下划线,作为数据表的字段名。
如果说,实体类信息与数据库信息不符,则需要自定义配置:
@TableName:用来指定表名;
@TableId:用来指定主键;
@TableField:用来指定普通字段。

主键字段可以通过 IdType 来定义类型:AUTO 自增、INPUT 自行输入、ASSIGN_ID 雪花算法。如果不指定类型,默认采用雪花算法生成 ID!
什么时候需要加注解:
① 成员变量名与数据库字段名不一致;
② 成员变量名以 is 开头且属于布尔类型;
③ 成员变量名与数据库关键字发生冲突(加转义字符);
④ 成员变量不是数据库字段(exist 为 false)

MyBatis-Plus 通过反射机制获取字段名的时候,会自动把 is 去掉,然后把剩余部分作为变量名,这就跟数据库不一致了。所以 is 开头且属于布尔类型的,必须加注解!
3. 常见配置
MyBatis-Plus 只适用于单表的增删改查,如果需要进行复杂的多表操作,还是要手写 SQL 语句的。
MyBatis-Plus 的配置项继承了 MyBatis 的原生配置,并增加了自己的特有配置。

除了 type-aliases-package,其实很多配置都是有默认值的,所以大多数都不用自己配!
三、核心功能
MyBatis-Plus 支持各种复杂的 where 条件,可以满足日常开发的所有需求。
1. 条件构造器
如图,Wrapper 即为条件构造器。

eq 等于,ge 大于等于,gt 大于,le 小于等于,lt 小于!

需求:
① 查询出名字中带 o 的,存款大于等于 1000 元的人的 id、username、info 和 balance 字段。
#SQL写法
select id, username, info, balance
from user
where username like '%o%' and balance >= 1000#MyBatis-Plus写法
@Test
void testQueryWrapper() {//1.构建查询条件QueryWrapper<User> wrapper = new QueryWrapper<User>().select("id", "username", "info", "balance").like("username", "o").ge("balance", 1000);//2.查询List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}
② 更新用户名为 jack 的用户的余额为 2000 元。
#SQL写法
update user
set balance = 2000
where username = 'jack'#MyBatis-Plus写法
@Test
void testUpdateWapper() {UpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = 2000").eq("username", "jack");userMapper.update(null, wrapper);
}
以上代码通过 QueryWrapper 和 UpdateWrapper 实现了复杂的查询和更新功能,但它的数据库字段名是被硬编码到代码中的,耦合度太高不易修改,所以我们推荐采用 Lambda 的方式构造条件,用字段对应的 get 函数代替字段名。


2. 自定义 SQL
问题描述: 用 MyBatis-Plus 构建 SQL 语句确实方便了很多,但是 MyBatis-Plus 更擅长的是 SQL 条件的构建,当我们遇到复杂的业务操作时,SQL 语句的前半部分只能采用硬编码的方式拼接在业务代码中,这样显然不符合常规的开发规范。
简单条件操作,直接传参即可;复杂条件操作,需要使用条件构造器;特别复杂的操作,为防止硬编码行为,只能自定义 SQL!
解决办法:SQL 语句的 where 部分交给 MyBatis-Plus 去做,而它的前半部分由我们自己定义。

核心思路: 将 MyBatis-Plus 构建好的条件往下传递,传给 Mapper 层,在 Mapper 层或者 xml 文件中,完成 SQL 语句的组装。
需求:
将 id 在指定范围的用户(例如 1、2、4)的余额扣减指定值。
① 基于 Wrapper 构建 where 条件
@Test
void testUpdateWapper() {List<Long> ids = List.of(1L, 2L, 4L);int amount = 200;LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>().in(User::getId, ids);userMapper.updateBalanceByIds(wrapper, amount);
}
② 在 mapper 方法参数中用 Param 注解声明 wrapper 变量名称
变量名称必须是 ew!
public interface UserMapper extends BaseMapper<User> {void updateBalanceByIds(@Param("ew") LambdaUpdateWrapper<User> wrapper, @Param("amount") int amount);
}
一般用常量 Constants.WRAPPER 代替 ex 会显得更加规范,要注意 Constants 的包路径不要导错!

③ 自定义 SQL,并使用 Wrapper 条件
${ew.customSqlSegment} 代表拼接自定义片段!
<mapper namespace="com.zxe.mp.mapper.UserMapper"><update id="updateBalanceByIds">update user set balance = balance - #{amount} ${ew.customSqlSegment}</update>
</mapper>
3. Service 接口
3.1 基本使用
相比 BaseMapper,Service 接口提供的功能更多更全。
Service 的内部实际上调用了 BaseMapper 接口,所有的方法都已经被实现好,我们只需要继承接口就行!

① 让我们的 UserService 接口继承 IService 接口

② 我们的实现类也继承 ServiceImpl 实现类
ServiceImpl<UserMapper, User> 的两个参数分别为要用到的 Mapper 和实体类!

③ 编写测试类,直接调用 Service 中的方法即可

Service 中的方法:查询单个 get 开头,查询多个 list 开头,复杂条件查询用 lambdaQuery,查询数量 count 开头,分页查询 page 开头,新增 save 开头,删除 remove 开头,修改 update 开头!
3.2 复杂条件
Service 的复杂条件用 lambdaQuery 和 lambdaQuery 实现。
复杂条件一般定义在业务层,Controller 层只负责向下传数据!
① 复杂查询
//复杂查询,统计数量用count,查询多个用list
List<User> users = this.lambdaQuery().like(name != null, User::getName, name).eq(status != null, User::getStatus, status).ge(minBalance != null, User::getBalance, minBalance).le(maxBalance != null, User::getBalance, maxBalance).list();
以上代码与下图功能一致:

② 复杂更新
//复杂更新,用update
this.lambdaUpdate().set(User::getBalance, remainBalance)//第一个参数是条件,后面的是操作.set(remainBalance == 0, User::getStatus, 2).eq(User::getId, id).update();
相关文章:
MyBatis-Plus 为简化开发而生【核心功能】
文章目录 一、前言二、快速入门1. 入门案例2. 常见注解3. 常见配置 三、核心功能1. 条件构造器2. 自定义 SQL3. Service 接口3.1 基本使用3.2 复杂条件 一、前言 顾名思义,MyBatis-Plus 其实是 MyBatis 的一个加强版,它可以帮助我们快速高效地编写数据库…...
【MySQL】(2) 库的操作
SQL 关键字,大小写不敏感。 一、查询数据库 show databases; 注意加分号,才算一句结束。 二、创建数据库 {} 表示必选项,[] 表示可选项,| 表示任选其一。 示例:建议加上 if not exists 选项。 三、字符集编码和排序…...
通信原理速成笔记(信息论及编码)
信息论基础 信息的定义与度量 信息是用来消除不确定性的内容。例如,在猜硬币正反的情境中,结果存在正反两种不确定性,而得知正确结果能消除这种不确定性,此结果即为信息。单个事件的信息量:对于离散信源中的事件xi&…...
云和恩墨亮相PolarDB开发者大会,与阿里云深化数据库服务合作
2025年2月26日,备受瞩目的阿里云PolarDB开发者大会于北京嘉瑞文化中心盛大举行,众多行业精英齐聚一堂,共襄技术盛会。云和恩墨作为阿里云重要的生态合作伙伴受邀参会。云和恩墨联合创始人兼技术研究院总经理杨廷琨与阿里云智能数据库产品事业…...
kafka consumer 手动 ack
在消费 Kafka 消息时,手动确认(acknowledge)消息的消费,可以通过使用 KafkaConsumer 类中的 commitSync() 或 commitAsync() 方法来实现。这些方法将提交当前偏移量,确保在消费者崩溃时不会重新消费已处理的消息。 以…...
final 关键字在不同上下文中的用法及其名称
1. final 变量 名称:final 变量(常量)。 作用:一旦赋值后,值不能被修改。 分类: final 实例变量:必须在声明时或构造函数中初始化。 final 静态变量:必须在声明时或静态代码块中初…...
PHP面试题--后端部分
本文章持续更新内容 之前没来得及整理时间问题导致每次都得找和重新背 这次整理下也方便各位小伙伴一起更轻松的一起踏入编程之路 欢迎各位关注博主不定期更新各种高质量内容适合小白及其初级水平同学一起学习 一起成为大佬 数组函数有那些 ps:本题挑难的背因为…...
Python 高精度计算利器:decimal 模块详解
Python 高精度计算利器:decimal 模块详解 在 Python 编程中,处理浮点数时,标准的 float 类型往往会因二进制表示的特性而产生精度问题。decimal 模块应运而生,它提供了十进制浮点运算功能,能让开发者在需要高精度计算…...
hbase相关问题处理
1.如果遇到ZK宕机,通过HTable和Connection两种连接方式获取数据,在实现原理和故障恢复上有何异同? 通过new HTable方式,则每次方法调用都会建立新的连接,而且会从zk获取表的元数据,会导致将业务的并发传导到zookeeper服务,会对全局所有依赖zookeeper服务的节点存在一定…...
Linux下的网络通信编程
在不同主机之间,进行进程间的通信。 1解决主机之间硬件的互通 2.解决主机之间软件的互通. 3.IP地址:来区分不同的主机(软件地址) 4.MAC地址:硬件地址 5.端口号:区分同一主机上的不同应用进程 网络协议…...
什么是“零日漏洞”(Zero-Day Vulnerability)?为何这类攻击被视为高风险威胁?
正文 零日漏洞(Zero-Day Vulnerability) 是指软件、硬件或系统中存在的、尚未被开发者发现或修复的安全漏洞。攻击者在开发者意识到漏洞存在之前(即“零日”内)利用该漏洞发起攻击,因此得名。这类漏洞的“零日”特性使…...
AI数据分析:用DeepSeek做数据清洗
在当今数据驱动的时代,数据分析已成为企业和个人决策的重要工具。随着人工智能技术的快速发展,AI 驱动的数据分析工具正在改变我们处理和分析数据的方式。本文将着重介绍如何使用 DeepSeek 进行数据清洗。 数据清洗是数据分析的基础,其目的是…...
把GB型材库放入solidwork中点击库无法应
1、文件夹的位置要选择对,如下图: 2、文件夹一定要嵌套三层,如下图...
【前端】XML,XPATH,与HTML的关系
XML与HTML关系 XML(可扩展标记语言)和 HTML(超文本标记语言)是两种常见的标记语言,但它们有不同的目的和用途。它们都使用类似的标记结构(标签),但在设计上存在一些关键的差异。 XML…...
IP-----动态路由OSPF(2)
这只是IP的其中一块内容,IP还有更多内容可以查看IP专栏,前一章内容为动态路由OSPF ,可通过以下路径查看IP-----动态路由OSPF-CSDN博客,欢迎指正 注意!!!本部分内容较多所以分成了两部分在上一章 5.动态路…...
《HelloGitHub》第 107 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、…...
leetcode_字典树 139. 单词拆分
139. 单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 思路: 定义状态: 设dp[i]表…...
计算机毕业设计Python+DeepSeek-R1大模型游戏推荐系统 Steam游戏推荐系统 游戏可视化 游戏数据分析(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
网络流算法: Dinic算法
图论相关帖子 基本概念图的表示: 邻接矩阵和邻接表图的遍历: 深度优先与广度优先拓扑排序图的最短路径:Dijkstra算法和Bellman-Ford算法最小生成树二分图多源最短路径强连通分量欧拉回路和汉密尔顿回路网络流算法: Edmonds-Karp算法网络流算法: Dinic算法 环境要求 本文所用…...
【Springboot】解决问题 o.s.web.servlet.PageNotFound : No mapping for *
使用 cursor 进行老项目更新为 springboot 的 web 项目,发生了奇怪的问题,就是 html 文件访问正常,但是静态文件就是 404 检查了各种配置,各种比较,各种调试,最后放弃时候,清理没用的配置文件&…...
Spring Boot 3.x 基于 Redis 实现邮箱验证码认证
文章目录 依赖配置开启 QQ 邮箱 SMTP 服务配置文件代码实现验证码服务邮件服务接口实现执行流程 依赖配置 <dependencies> <!-- Spring Boot Starter Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spr…...
PostgreSQL10 物理流复制实战:构建高可用数据库架构!
背景 PostgreSQL 10 在高可用架构中提供了物理复制,也称为流复制(Streaming Replication),用于实现实例级别的数据同步。PostgreSQL 复制机制主要包括物理复制和逻辑复制:物理复制依赖 WAL 日志进行物理块级别的同步&…...
从零开始开发纯血鸿蒙应用之语音朗读
从零开始开发纯血鸿蒙应用 〇、前言一、API 选型1、基本情况2、认识TextToSpeechEngine 二、功能集成实践1、改造右上角菜单2、实现语音播报功能2.1、语音引擎的获取和关闭2.2、设置待播报文本2.3、speak 目标文本2.4、设置语音回调 三、总结 〇、前言 中华汉字洋洋洒洒何其多…...
RabbitMQ系列(五)基本概念之Queue
在 RabbitMQ 中,Queue(队列) 是存储消息的容器,也是消息传递的核心载体。以下是其核心特性与作用的全方位解析: 一、Queue 的定义与核心作用 消息存储容器 Queue 是 RabbitMQ 中实际存储消息的实体,生产者…...
奔图Pantum M7165DN黑白激光打印一体机报数据清除中…维修
故障描述: 一台奔图Pantum M7165DN黑白激光打印一体机开机自检正常,自检过后就不能工作了,按键面板无任何反应一直提示数据清除中…,如果快速操作的话也能按出菜单、功能啥的,不过一会又死机了,故障请看下图: 故障检修: 经分析可能是主板数据出现了问题,看看能不能快速…...
TP-LINK路由器如何设置网段、网关和DHCP服务
目标 ①将路由器的网段由192.168.1.XXX改为192.168.5.XXX ②确认DHCP是启用的,并将DHCP的IP池的范围设置为排除自己要手动指定的IP地址,避免IP冲突。 01-复位路由器 路由器按住复位键10秒以上进行重置操作 02-进入路由器管理界面 电脑连接到路由器&…...
神经网络代码入门解析
神经网络代码入门解析 import torch import matplotlib.pyplot as pltimport randomdef create_data(w, b, data_num): # 数据生成x torch.normal(0, 1, (data_num, len(w)))y torch.matmul(x, w) b # 矩阵相乘再加bnoise torch.normal(0, 0.01, y.shape) # 为y添加噪声…...
设计一个“车速计算”SWC,通过Sender-Receiver端口输出车速信号。
1. 需求分析 功能目标:根据车轮脉冲信号(轮速传感器输入)计算当前车速,并将结果通过Sender端口发送给其他SWC。 输入:轮速脉冲数(如WheelPulse,类型uint32)。 输出:车速(如VehicleSpeed,类型float32,单位km/h)。 触发方式:周期性计算(例如每10ms执行一次)。 2.…...
TCP/IP 5层协议簇:网络层(IP数据包的格式、路由器原理)
目录 1. TCP/IP 5层协议簇 2. IP 三层包头协议 3. 路由器原理 4. 交换机和路由的对比 1. TCP/IP 5层协议簇 如下: 2. IP 三层包头协议 数据包如下:IP包头不是固定的,每一个数字是一个bit 其中数据部分是上层的内容,IP包头最…...
1JVM概念
JVM(Java虚拟机)详解 1. 基本概念与作用 JVM(Java Virtual Machine)是Java程序的运行环境,负责将编译后的字节码(.class文件)解释或编译为机器指令执行,并管理内存、线程、安全…...
