mybatisPlus高级篇
文章目录
- 主键生成策略介绍
- AUTO策略
- INPUT策略
- ASSIGN_ID策略
- ASSIGN_UUID策略
- NONE策略
- MybatisPlus分页
- 分页插件
- 自定义分页插件
- ActiveRecord模式
- SimpleQuery工具类
- SimpleQuery介绍
- list
- map
- Group
主键生成策略介绍
- 主键:在数据库中,主键通常用于快速查找和访问数据。主键是数据库表中的一列或一组列,用于唯一标识表中的每一行数据。主键必须具有唯一性,而且主键值不能为NULL。主键可以用来确保数据的完整性和一致性,还可以用于建立表之间的关系。
- 在MybatisPlus中提供了一个注解,是
@TableId,该注解提供了各种的主键生成策略,通过使用该注解来对于新增的数据指定主键生成策略。在新增数据的时候,数据就会按照指定的主键生成策略来生成对应的主键。
AUTO策略
- 该策略为跟随数据库表的主键递增策略
- 当使用AUTO策略(自动递增)来生成主键值时,数据库主键的类型应设置为整数类型(如INT、BIGINT等),以便能够自动递增并确保唯一性。这是因为自动递增主键会自动为每个新插入的行生成一个唯一的整数值,而整数类型可以更有效地存储和处理这些值。
- 前提是数据库表的主键要设置为自增,此处要设置好下次递增的数字


- 实体类添加注解,指定主键生成策略
@TableId(type = IdType.AUTO)private Long id;
INPUT策略
- 对于INPUT策略,数据库主键的类型可以是任何合适的数据类型,根据具体的需求来确定。
- INPUT策略意味着主键的值是由用户手动输入或提供的,而不是由数据库自动生成。因此,主键可以是任何合法的数据类型,如整数、字符串、日期等,取决于业务需求和数据的特性。需要注意的是,需要确保主键的值在表中是唯一的,以维护数据的完整性和一致性。
@TableId(type = IdType.INPUT)private Long id;
ASSIGN_ID策略
- ASSIGN_ID策略是一种手动分配主键值的策略。主键的类型可以是任何合适的数据类型,根据具体的需求来确定。
- 如果不设置类型值,默认则使用
IdType.ASSIGN_ID策略(自 3.3.0 3.3.0 3.3.0起)。该策略会使用雪花算法自动生成主键ID,主键类型为长或字符串(分别对应的MySQL的表字段为BIGINT和VARCHAR) - 需要注意的是,需要确保主键的值在表中是唯一的,以维护数据的完整性和一致性。
- 雪花算法是由一个64位的二进制组成的,最终就是一个Long类型的数值。主要分为四部分存储:
- 位的符号位,固定值为0
- 41位的时间戳
- 10位的机器码,包含5位机器id和5位服务id
- 12位的序列号

@TableId(type = IdType.ASSIGN_ID)private Long id;
ASSIGN_UUID策略
- UUID(Universally Unique Identifier)全局唯一标识符,定义为一个字符串主键,采用32位数字组成,编码采用16进制,定义了在时间和空间都完全唯一的系统信息。
- UUID的编码规则:
- 1~8位采用系统时间,在系统时间上精确到毫秒级保证时间上的唯一性;
- 9~16位采用底层的IP地址,在服务器集群中的唯一性;
- 17~24位采用当前对象的HashCode值,在一个内部对象上的唯一性;
- 25~32位采用调用方法的一个随机数,在一个对象内的毫秒级的唯一性。
- 使用UUID作为MySQL主键时,主键类型应选择
VARCHAR类型。UUID是一个36位的字符串,由32位的十六进制数字和4个连字符组成。因此,需要使用VARCHAR(36)来存储UUID。
@TableId(type = IdType.ASSIGN_UUID)private String id;
NONE策略
- NONE策略表示不指定主键生成策略,当我们没有指定主键生成策略或者主键策略为NONE的时候,跟随的是全局策略。全局默认配置
id-type使用的是雪花算法。
@TableId(type = IdType.NONE)private Long id;
MybatisPlus分页
分页插件
-
分页的本质就是需要设置一个拦截器,通过拦截器拦截了SQL,通过在SQL语句的结尾添加limit关键字,来实现分页的效果。
-
配置的步骤
- 通过配置类来指定一个具体数据库的分页插件,因为不同的数据库的方言不同,具体生成的分页语句也会不同。
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}
- 实现分页查询效果
@Test
void selectPage(){//1.创建QueryWrapper对象LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();//2.创建分页查询对象,指定当前页和每页显示条数IPage<User> page = new Page<>(1,3);//3.执行分页查询userMapper.selectPage(page, lambdaQueryWrapper);//4.查看分页查询的结果System.out.println("当前页码值:"+page.getCurrent());System.out.println("每页显示数:"+page.getSize());System.out.println("总页数:"+page.getPages());System.out.println("总条数:"+page.getTotal());System.out.println("当前页数据:"+page.getRecords());
}
- 查询语句查看

自定义分页插件
在某些场景下,需要自定义SQL语句来进行查询。接下来演示一下自定义SQL的分页操作
- 在
UserMapper.xml映射配置文件中提供查询语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.powernode.mapper.UserMapper"><select id="selectByName" resultType="com.powernode.domain.User">select * from powershop_user where name = #{name}</select>
</mapper>
- 在
Mapper接口中提供对应的方法,方法中将IPage对象作为参数传入
@Mapper
public interface UserMapper extends BaseMapper<User> {IPage<User> selectByName(IPage<User> page, String name);
}
- 实现分页查询效果
@Test
void selectPage2(){//1.创建分页查询对象,指定当前页和每页显示条数IPage<User> page = new Page<>(1,2);//2.执行分页查询userMapper.selectByName(page,"Mary");//3.查看分页查询的结果System.out.println("当前页码值:"+page.getCurrent());System.out.println("每页显示数:"+page.getSize());System.out.println("总页数:"+page.getPages());System.out.println("总条数:"+page.getTotal());System.out.println("当前页数据:"+page.getRecords());
}
ActiveRecord模式
- ActiveRecord(活动记录,简称AR),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。
- ActiveRecord 一直广受解释型动态语言( PHP 、 Ruby 等)的喜爱,通过围绕一个数据对象进行CRUD操作。而 Java 作为准静态(编译型)语言,对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索,仅仅需要让实体类继承 Model 类且实现主键指定方法,即可开启 AR 之旅。
- 实现步骤
- 让实体类继承Model类
@Data @AllArgsConstructor @NoArgsConstructor public class User extends Model<User> {private Long id;private String name;private Integer age;private String email; }- Model类中提供了一些增删改查方法,可以直接使用实体类对象调用这些增删改查方法,简化了操作的语法,但底层依然是需要UserMapper,所以持久层接口并不能省略
- 测试ActiveRecord模式的增删改查
- 添加数据
@Test void activeRecordAdd(){User user = new User();user.setName("wang");user.setAge(35);user.setEmail("wang@powernode.com");user.insert(); }- 删除数据
@Test void activeRecordDelete(){User user = new User();user.setId(8L);user.deleteById(); }- 修改数据
@Test void activeRecordUpdate(){User user = new User();user.setId(6L);user.setAge(50);user.updateById(); }- 查询数据
@Test void activeRecordSelect(){User user = new User();user.setId(6L);User result = user.selectById();System.out.println(result); }
SimpleQuery工具类
SimpleQuery介绍
- SimpleQuery可以对selectList查询后的结果用Stream流进行了一些封装,使其可以返回一些指定结果,简洁了api的调用
list
- 演示基于字段封装集合
@Test
void testList(){//.list()方法执行查询,并返回符合条件的用户列表//使用.list(User::getId)来指定返回的字段为IDList<Long> ids = SimpleQuery.list(new LambdaQueryWrapper<User>().eq(User::getName, "Mary"), User::getId);System.out.println(ids);
}
- 演示对于封装后的字段进行lambda操作
@Test
void testList2(){/* e -> Optional.of(e.getName()).map(String::toLowerCase).ifPresent(e::setName)额外的逻辑处理,即对返回的姓名进行转换Optional.of(e.getName())用于将姓名转换为Optional对象,以便进行后续的操作。接着,.map(String::toLowerCase)将姓名转换为小写形式。最后,.ifPresent(e::setName)将转换后的小写姓名设置回User对象的姓名属性。*/List<String> names = SimpleQuery.list(new LambdaQueryWrapper<User>().eq(User::getName, "Mary"),User::getName,e -> Optional.of(e.getName()).map(String::toLowerCase).ifPresent(e::setName));System.out.println(names);
}
map
- 演示将所有的对象以id,实体的方式封装为Map集合
@Test
void testMap(){//将所有元素封装为Map形式Map<Long, User> idEntityMap = SimpleQuery.keyMap(new LambdaQueryWrapper<>(), User::getId);System.out.println(idEntityMap);
}
- 演示将单个对象以id,实体的方式封装为Map集合
@Test
void testMap2(){//将单个元素封装为Map形式Map<Long, User> idEntityMap = SimpleQuery.keyMap(new LambdaQueryWrapper<User>().eq(User::getId,1L), User::getId);System.out.println(idEntityMap);
}
- 演示只想要id和name组成的map
@Test
void testMap3(){//只想要只想要id和name组成的mapMap<Long, String> idNameMap = SimpleQuery.map(new LambdaQueryWrapper<>(), User::getId, User::getName);System.out.println(idNameMap);
}
Group
- 演示分组效果
@Test
void testGroup(){Map<String, List<User>> nameUsersMap = SimpleQuery.group(new LambdaQueryWrapper<>(), User::getName);System.out.println(nameUsersMap);
}
相关文章:
mybatisPlus高级篇
文章目录 主键生成策略介绍AUTO策略INPUT策略ASSIGN_ID策略ASSIGN_UUID策略NONE策略 MybatisPlus分页分页插件自定义分页插件 ActiveRecord模式SimpleQuery工具类SimpleQuery介绍listmapGroup 主键生成策略介绍 主键:在数据库中,主键通常用于快速查找和…...
Rust之包、单元包及模块
包:一个用于构建、测试并分享单元包的Cargo功能;单元包:一个用于生成库或可执行文件的树形模块结构;模块及use关键字:被用于控制文件结构、作用域及路径的私有性;路径:一种用于命名条目的方法&a…...
内存函数讲解
💕"痛苦难以避免,而磨难可以选择。"-->村上春树💕 作者:Mylvzi 文章主要内容:数据在内存中的存储 内存函数就是管理内存数据的函数,包含于头文件<string.h>中 1.memcpy函数-->内存…...
C语言假期作业 DAY 01
题目 1.选择题 1、执行下面程序,正确的输出是( ) int x5,y7; void swap() { int z; zx; xy; yz; } int main() { int x3,y8; swap(); printf("%d,%d\n",x, y)…...
2023牛客暑期多校-J-Qu‘est-ce Que C‘est?(DP)
题意: 给定长度为n的数列,要求每个数都在的范围,且任意长度大于等于2的区间和都大于等于0,问方案数。。 思路: 首先要看出是dp题,用来表示遍历到第i位且后缀和最小为x的可行方案数(此时的后缀可以只有最…...
【141. 环形链表】
来源:力扣(LeetCode) 描述: 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环&#x…...
ORB特征笔记
简介 ORB Oriented FAST Rotated BRIEF 前面的Oriented FAST说明的是它的关键点的选取是一种改良过的FAST,在FAST的基础上加了方向信息;后面的Rotated BRIEF是指特征描述符使用BRIEF描述子(Binary Robust Independent Elementary Featur…...
12.Netty源码之整体架构脉络
Netty 整体架构脉络 Netty 的逻辑处理架构为典型网络分层架构设计,共分为网络通信层、事件调度层、服务编排层,每一层各司其职。 网络通信层 网络通信层的职责是执行网络 I/O 的操作。它支持多种网络协议和 I/O 模型的连接操作。当网络数据读取到内核缓冲…...
【ArcGIS Pro二次开发】(54):三调名称转用地用海名称
三调地类和用地用海地类之间有点相似但并不一致。 在做规划时,拿到的三调,都需要将三调地类转换为用地用海地类,然后才能做后续的工作。 一般情况下,三调转用地用海存在【一对一,多对一和一对多】3种情况。 前2种情况…...
3D Tiles官方示例资源下载链接
本文列出Cesium官方提供的 3D Tiles 1.0和1.1规范的9个示例切块集(tileset)。 有关如何使用本地服务器托管这些示例的详细信息,请参阅 INSTRUCTIONS.md。 推荐:用 NSDT设计器 快速搭建可编程3D场景。 1、Metadata Granularities …...
【Java】分支结构习题
【Java】分支结构 文章目录 【Java】分支结构题1 :数字9 出现的次数题2 :计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值。题3 :猜数字题4 :牛客BC110 X图案题5 :输出一个整数的每一位题6 : 模拟三次密码输…...
删除主表 子表外键没有索引的性能优化
整个表147M,执行时一个CPU耗尽, buffer gets 超过1个G, 启用并行也没有用 今天开发的同事问有个表上的数据为什么删不掉?我看了一下,也就不到100000条数据,表上有外键,等了5分钟hang在那里&…...
面向切面编程AOP
面向切面编程简介 IoC使软件组件松耦合。AOP让你能够捕捉系统中经常使用的功能,把它转化成组件。 AOP(Aspect Oriented Programming):面向切面编程,面向方面编程。(AOP是一种编程技术) AOP是对…...
大学生活题解
样例输入: 3 .xA ... Bx.样例输出: 6思路分析: 这道题只需要在正常的广搜模板上多维护一个— —方向,如果当前改变方向,就坐标不变,方向变,步数加一;否则坐标变,方向不…...
flask的配置项
flask的配置项 为了使 Flask 应用程序正常运行,有多种配置选项需要考虑。下面是一些基本的 Flask 配置选项: DEBUG: 这个配置项决定 Flask 是否应该在调试模式下运行。如果这个值被设为 True,Flask 将会提供更详细的错误信息,并…...
暑假刷题第16天--7/28
143. 最大异或对 - AcWing题库(字典树) #include<iostream> using namespace std; const int N100005; int a[N]; int nex[10000007][2],cnt; void insert(int x){int p0;for(int i30;i>0;i--){int ux>>i&1;if(!nex[p][u])nex[p][u]…...
vue vite ts electron ipc arm64
初始化 npm init vue # 全选 yes npm i # 进入项目目录后使用 npm install electron electron-builder -D npm install commander -D # 额外组件增加文件 新建 plugins 文件夹 src/background.ts 属于主进程 ipcMain.on、ipcMain.handle 都用于主进程监听 ipc,…...
数据分析-关于指标和指标体系
一、电商指标体系 二、指标体系的作用 三、统计学中基本的分析手段...
Vue+ElementUI操作确认框及提示框的使用
在进行数据增删改查操作中为保证用户的使用体验,通常需要显示相关操作的确认信息以及操作结果的通知信息。文章以数据的下载和删除提示为例进行了简要实现,点击下载以及删除按钮,会出现对相关信息的提示,操作结果如下所示。 点击…...
宋浩线性代数笔记(二)矩阵及其性质
更新线性代数第二章——矩阵,本章为线代学科最核心的一章,知识点多而杂碎,务必仔细学习。 重难点在于: 1.矩阵的乘法运算 2.逆矩阵、伴随矩阵的求解 3.矩阵的初等变换 4.矩阵的秩 (去年写的字,属实有点ugl…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
