重生之我在暑假学习微服务第二天《MybatisPlus-下篇》

本系列参考黑马程序员微服务课程,有兴趣的可以去查看相关视频,本系列内容采用渐进式方式讲解微服务核心概念与实践方法,每日更新确保知识点的连贯性。通过系统化学习路径帮助开发者掌握分布式系统构建的关键技术。读者可通过平台订阅功能获取最新章节推送,及时了解服务拆分、容器化部署、服务网格等前沿技术动态。
 

  •  个人主页:VON
  • 文章所属专栏:微服务
  • 系列文章链接:重生之我在暑假学习微服务第一天《MybatisPlus-上篇》-CSDN博客
  • 时间:每天12点准时更新

特别声明:本篇文章对应黑马程序员微服务课程P11-P20 

目录

前言 

一、安装插件

MyBatis-Plus 插件的意义

1.找到idea中的插件

2.在插件市场中搜索MyBatisPlus插件

3. 配置所需信息

4. 配置成自己的

5.接下来就可以直接使用了

6.开始生成

二、DB静态工具

测试一:改造根据id查询

1.先导入AddressVO

 2.在UserVO中添加AddressVO字段​编辑

3.开始修改代码

4.用Apifox测试

测试二:改造根据id批量查询 

1.还是先改造Controll层代码

 2.实现方法

3.解释方法

(1)查询用户基本信息

(2)查询用户地址信息

(3)地址信息处理和分组

(4)封装最终结果

4、测试结果

三、逻辑删除

1.先配置逻辑删除相关语句

2.新建一个测试

 3.测试结果

4.查看数据库表结构 

四、处理器

MyBatis-Plus 中的处理器

元对象处理器(MetaObjectHandler)

分页插件处理器(PaginationInnerInterceptor)

动态表名处理器(DynamicTableNameInnerInterceptor)

乐观锁处理器(OptimisticLockerInnerInterceptor)

SQL 注入处理器(AbstractSqlInjector)

性能分析处理器(PerformanceInterceptor)

注意事项

1、枚举处理器

(1)新建一个枚举文件来存放枚举类型

(2)配置枚举处理器​编辑

 (3)修改实体类

 (4)修改代码

(5)测试 

2、JSON处理器

五、分页插件

1、先配置实体类

2、测试

 六、分页查询案例

1、先创建实体类 

​编辑 2、用户继承该实体类

3、定义返回结果

 4、开始测试

mybatisplus篇结尾

总结与展望


 

前言 

窗外的蝉鸣又起时,VON 的笔记本已经写满半本。晨光漫过屏幕,照亮他眼下淡淡的青黑 —— 凌晨三点才在代码调试成功的提示音里睡去,七点却被生物钟拽醒。​

他点开《MyBatisPlus 基础入门》的第三章,指尖在手机屏幕上飞快滑动。@TableName 注解那页还粘着昨晚吃泡面时溅的汤渍,此刻倒成了醒目的标记。"原来实体类和数据库表名不一致时,加这个注解就能映射..." 他对着示例敲下代码,看着控制台弹出的 "查询成功" 提示,突然想起前世写的那堆冗长 SQL,耳根发烫。​

条件构造器是块硬骨头。QueryWrapper 的嵌套查询让他卡了整整两小时,报错信息像密集的蚂蚁爬满屏幕。窗外的蝉鸣又开始聒噪,他抓着头发盯着那句 "LambdaQueryWrapper lqw = new LambdaQueryWrapper<>()",忽然想起班长发的资料里提过" 链式调用更直观 "。指尖在键盘上重新跳跃,当根据年龄和性别筛选出的用户列表整齐排列在控制台时,他狠狠捶了下桌面,震得马克杯里的速溶咖啡泛起涟漪。​

自定义 SQL 部分倒意外顺利。或许是前世被冗余代码折磨出的本能,当他在 XML 文件里写出带条件判断的动态 SQL 时,竟有种莫名的熟悉感。阳光穿过纱窗在代码上投下格子影,他忽然发现,那些曾经让他望而生畏的尖括号,此刻正像列队的士兵般温顺。​

下午三点,Service 接口的批量新增测试成功。看着一百条用户数据瞬间写入数据库,VON 摸出手机翻到游戏群,前世此刻他本该在喊 "开团"。群里依旧热闹,他却平静地点了退出。​

最后一行代码运行结束时,晚霞正把天空染成橘红色。VON 合上笔记本,发现封面上的倒影里,自己的眼睛比昨天更亮了些。蝉鸣渐歇的暮色里,他仿佛听见未来的自己敲代码的声音,清脆又笃定。

至此,MybatisPlus篇完结!!!

一、安装插件

MyBatis-Plus 插件的意义

MyBatis-Plus(简称 MP)是基于 MyBatis 的增强工具插件,旨在简化开发、提升效率。其核心意义在于为 MyBatis 提供更便捷的功能扩展,同时保持与原生 MyBatis 的无缝兼容。

1.找到idea中的插件

2.在插件市场中搜索MyBatisPlus插件

3. 配置所需信息

4. 配置成自己的

 

这里测试的时候报错了,问了下豆包,说是时区问题。

The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support. 

修改方案:

这样就表示成功了 

5.接下来就可以直接使用了

可以看到这里出现的表正是我们数据库中的表

6.开始生成

配置成我这样就可以

 出现这个标志就成功了

这些全都是这个插件生成的代码 

 

二、DB静态工具

DB静态工具是指用于数据库设计、分析、优化的非运行时工具,通常在数据库开发或维护阶段使用。这类工具不直接与运行中的数据库交互,而是通过静态分析数据结构、SQL脚本或元数据来提供支持。

测试一:改造根据id查询

1.先导入AddressVO

 2.在UserVO中添加AddressVO字段

3.开始修改代码

 原UserController

 现UserController

 实现方法

4.用Apifox测试

测试成功

测试二:改造根据id批量查询 

1.还是先改造Controll层代码

 2.实现方法

@Overridepublic List<UserVO> queryUsersAndAddressByIds(List<Long> ids) {//1.查询用户List<User> users = listByIds(ids);if(CollUtil.isEmpty(users)){return Collections.emptyList();}//2.查询地址//获取id集合List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());List<Address> address = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();List<AddressVO> addressVOList = BeanUtil.copyToList(address, AddressVO.class);Map<Long, List<AddressVO>> addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));//3.封装VOList<UserVO> userVOList = BeanUtil.copyToList(users, UserVO.class);userVOList.forEach(userVO -> {userVO.setAddress(addressMap.get(userVO.getId()));});return userVOList;}

3.解释方法

这个方法有点复杂了,这里解释一下相关步骤

(1)查询用户基本信息
List<User> users = listByIds(ids);
if(CollUtil.isEmpty(users)){return Collections.emptyList();
}
  • 使用 listByIds(ids) 方法根据ID列表批量查询用户
  • 如果查询结果为空,则返回空列表
(2)查询用户地址信息
List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());
List<Address> address = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();
  • 从查询到的用户列表中提取所有用户ID
  • 使用 Db.lambdaQuery() 构造查询条件,通过 in 条件批量查询这些用户的所有地址信息
(3)地址信息处理和分组
List<AddressVO> addressVOList = BeanUtil.copyToList(address, AddressVO.class);
Map<Long, List<AddressVO>> addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));
  •  使用 BeanUtil.copyToList() 将 Address 对象列表转换为 AddressVO 对象列表
  • 使用 Collectors.groupingBy() 按用户ID对地址进行分组,形成 Map<用户ID, 地址列表> 的结构
(4)封装最终结果
List<UserVO> userVOList = BeanUtil.copyToList(users, UserVO.class);
userVOList.forEach(userVO -> {userVO.setAddress(addressMap.get(userVO.getId()));
});
return userVOList;
  • 将用户信息转换为 UserVO 对象列表
  • 遍历每个 UserVO 对象,从 addressMap 中获取对应用户ID的地址列表并设置到 UserVO 中
  • 返回封装好的用户VO列表

4、测试结果

可以看到可以正常查询

三、逻辑删除

逻辑删除是一种数据管理方式,通过标记记录的状态而非物理删除数据。通常通过添加一个字段(如 is_deletedstatus)标识记录是否“已删除”,实际数据仍保留在数据库中。

1.先配置逻辑删除相关语句

2.新建一个测试

 3.测试结果

4.查看数据库表结构 

 不难看出这里的deleted字段变成了true,说明已经被逻辑删除掉了

四、处理器

MyBatis-Plus 中的处理器

MyBatis-Plus 提供了多种处理器(Handler)用于扩展或定制框架行为,主要分为以下几类:

元对象处理器(MetaObjectHandler)

用于自动填充公共字段(如创建时间、更新时间、操作人等)。通过实现 MetaObjectHandler 接口并重写以下方法:

@Override
public void insertFill(MetaObject metaObject) {// 插入时自动填充字段this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
}@Override
public void updateFill(MetaObject metaObject) {// 更新时自动填充字段this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}

需通过 @Component 注解注册为 Spring Bean。

分页插件处理器(PaginationInnerInterceptor)

用于实现物理分页功能,需通过配置类启用:

@Configuration
public class MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor());return interceptor;}
}

支持多种数据库方言,自动识别并转换分页语句。

动态表名处理器(DynamicTableNameInnerInterceptor)

用于动态替换表名,适用于分表场景:

DynamicTableNameInnerInterceptor interceptor = new DynamicTableNameInnerInterceptor();
interceptor.setTableNameHandler((sql, tableName) -> {return "实际表名逻辑";
});

乐观锁处理器(OptimisticLockerInnerInterceptor)

通过版本号实现乐观锁,需在实体类字段添加 @Version 注解:

@Version
private Integer version;

配置拦截器后,更新操作会自动检测版本号一致性。

SQL 注入处理器(AbstractSqlInjector)

用于自定义全局 SQL 方法,需继承 AbstractSqlInjector 并实现 inspectInject 方法:

public class CustomSqlInjector extends AbstractSqlInjector {@Overridepublic List<AbstractMethod> getMethodList() {return Stream.of(new InsertBatchSomeColumn()).collect(Collectors.toList());}
}

性能分析处理器(PerformanceInterceptor)

已废弃,推荐使用第三方监控工具(如 P6Spy)替代。

注意事项
  • 处理器需通过 MybatisPlusInterceptoraddInnerInterceptor 方法添加
  • 多个拦截器按添加顺序执行
  • 部分处理器需配合注解或实体类字段使用

可以看到处理器的类型十分丰富,这里给大家详解一下以下两个处理器的使用

1、枚举处理器

(1)新建一个枚举文件来存放枚举类型

(2)配置枚举处理器

 (3)修改实体类

 (4)修改代码

将出现的状态码都修改一下

UserVO实体类也要改一下 

(5)测试 

测试一下观察返回值 

这里返回值变成了枚举类型的,这可不是我们想要的结果

 解决方案也很简单,只需要添加这么一个注解即可

 

可以看到这是展现的就是我们预期的效果了 

2、JSON处理器

JSON 处理器是一种用于解析、生成、转换和操作 JSON(JavaScript Object Notation)数据的工具或库。其核心功能包括:

  • 解析:将 JSON 字符串转换为编程语言中的数据结构(如对象、字典、数组等)。
  • 序列化:将内存中的数据结构转换为 JSON 字符串。
  • 查询与修改:支持路径查询(如 JSONPath)、节点增删改查等操作。
  • 验证:检查 JSON 数据是否符合特定模式(如 JSON Schema)。
  • 格式化:美化或压缩 JSON 字符串以提高可读性或传输效率。

先创建实体类

注:要和表中数据保持一致 

 这里的字段也要加一下注解

 

添加这一字段

这里也要修改一下,凡是涉及到的都要修改

 就像这样的,都要修改为上面那种

 UserVO实体类也要改

改为UserInfo

测试

不难看出这里的info字段变成了json格式

五、分页插件

分页插件是一种用于将大量数据分割成多个页面的工具,通常用于网页或应用程序中,以提高数据加载效率和用户体验。它允许用户通过导航按钮(如上一页、下一页、页码跳转)浏览不同页面的数据,避免一次性加载全部内容。

1、先配置实体类

2、测试

注意一下这里的page包,别导入错了

这里当时添加数据后忘记删除了

可以看到我们设置的每页2条数据,5条数据正好三页。

 六、分页查询案例

1、先创建实体类 

 2、用户继承该实体类

3、定义返回结果

 

 4、开始测试

service层代码

@Overridepublic PageDTO<UserVO> queryUsersPage(UserQuery query) {String name = query.getName();Integer status = query.getStatus();Page<User> page = new Page<>(query.getPageNo(), query.getPageSize());if(StrUtil.isNotBlank(query.getSortBy())){//不为空page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));}else{page.addOrder(new OrderItem("update_time", false));}Page<User> p = lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).page( page);//封装PageDTO<UserVO> dto = new PageDTO<>();dto.setTotal(p.getTotal());dto.setPages(p.getPages());List<User> records = p.getRecords();if(records != null){List<UserVO> vos = BeanUtil.copyToList(records, UserVO.class);dto.setList(vos);}return dto;}

测试结果 

mybatisplus篇结尾

MyBatis-Plus作为一款强大的MyBatis增强工具,极大简化了开发者的数据库操作流程,提升了开发效率。通过自动生成代码、内置通用Mapper和Service,开发者可以专注于业务逻辑的实现,减少重复性工作。

MyBatis-Plus支持多种数据库,并提供丰富的查询条件构造器,满足复杂查询需求。其强大的性能优化和灵活的插件机制,使得数据库操作更加高效和安全。无论是新项目搭建还是旧项目改造,MyBatis-Plus都能提供便捷的解决方案。

在实际开发中,合理使用MyBatis-Plus的功能,可以显著提升开发效率和代码质量。结合Spring Boot等框架,能够快速构建稳定可靠的企业级应用。持续关注MyBatis-Plus的更新和社区动态,能够更好地利用其最新特性。

总结与展望

MyBatis-Plus的未来发展潜力巨大,随着技术的不断进步,更多实用功能将被引入。开发者应持续学习和实践,充分利用MyBatis-Plus的优势,构建高效、可维护的应用程序。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统整理Python的条件语句和常用方法

Python 的条件语句&#xff08;if 语句&#xff09;是控制程序流程的基础之一&#xff0c;结构清晰、语法简洁&#xff0c;非常适合初学者掌握。一、基本语法结构if 条件:执行代码块1 elif 条件2:执行代码块2 else:执行代码块3示例&#xff1a;score 85if score > 90:print…

记录个IAR程序下载后硬件复位不运行,必须断电复位才运行的问题

【问题测试】有个F407的跑马灯的例子&#xff0c;是MDK和IAR两个版本&#xff0c;MDK版本的例子下载并复位后可以正常看到LED闪烁&#xff0c;而IAR的例子下进去后&#xff0c;不会闪烁。使用TOOL的上位机内核寄存器监测工具测试发现&#xff0c;硬件复位后竟然还在调试状态&am…

观察者模式(Observer Pattern)和 发布-订阅模式(Publisher-Subscriber Pattern)

你对 观察者模式&#xff08;Observer Pattern&#xff09;和 发布-订阅模式&#xff08;Publisher-Subscriber Pattern&#xff09;的描述是非常准确的&#xff0c;并且阐明了它们的核心区别。为了帮助你更好地理解这两者的细微差异&#xff0c;下面是一个更详细的对比分析&am…

2025年接口技术的十字路口:当MCP遇见REST、GraphQL与gRPC

在当今这个由数据驱动、万物互联的时代&#xff0c;应用程序接口&#xff08;API&#xff09;已成为现代软件架构的基石。它们是不同服务之间沟通的桥梁&#xff0c;支撑着从网页应用到复杂的微服务生态系统的一切。长久以来&#xff0c;开发者们在REST、GraphQL和gRPC这几种主…

【CTF-WEB-反序列化】利用__toString魔术方法读取flag.php

题目 页面提示输入?code&#xff0c;那我们在网址里get一下出现了新页面的提示&#xff0c;进入看看下面有个help.php页面的提示&#xff0c;进入看看有一段php代码&#xff0c;仔细分析&#xff0c;应该是要用反序列法代码如下 class FileClass{ public $filename error.log…

在 github.com 与 sourceforge.net 上创建免费个人静态网站、博客的区别

github.com github 属于 git 版本管理专业网站&#xff0c;有免费和收费两种套餐。git 的数据是存放在数据库中的&#xff0c;要将数据库中的数据显示为网站的网页&#xff0c;这需要服务器端提供专门的中间件支持才能实现。 特点&#xff1a; 官方支持&#xff1a;提供长期…

jenkins 入门指南:从安装到启动的完整教程

jenkins 入门指南&#xff1a;从安装到启动的完整教程 持续集成&#xff08;CI&#xff09;是现代开发流程中的核心环节&#xff0c;而 Jenkins 作为一款开源的 CI 工具&#xff0c;凭借简单安装、开箱即用、插件丰富、易于扩展等优势&#xff0c;成为开发者的首选工具。它能自…

机器学习(重学版)基础篇(概念与评估)

本篇参考周志华老师的西瓜书&#xff0c;但是本人学识有限仅能理解皮毛&#xff0c;如有错误诚请读友评论区指正&#xff0c;万分感谢。一、基础概念与评估方法本节目标&#xff1a;建立理论基础框架​1、机器学习定义机器学习是一门通过计算手段利用经验&#xff08;以数据形式…

spring/springboot SPI(二)配合使用的接口

spring.factories 里&#xff0c;Spring 会根据接口来加载实现类&#xff0c;常见的几个接口包括&#xff1a;一、org.springframework.context.ApplicationListener1、作用监听 Spring 容器事件&#xff0c;如 ApplicationReadyEvent。2、使用方法项目结构Spring Boot 2.xSpri…

基于Zig语言,opencv相关的c++程序静态交叉编译

一、写在前面 1.什么是zig? Zig 是一种通用编程语言&#xff1b; Zig 最初的定位就是代替C语言的系统级语言&#xff0c;它提供了与 C 语言几乎 100% 兼容&#xff08;可直接调用 C 头文件、链接 C 库&#xff09;&#xff0c;同时不需要任何依赖构建系统。 Zig 同时附带一…

基于 LSTM 与 SVM 融合的时间序列预测模型:理论框架与协同机制—实践算法(1)

目录 1、单一模型的局限性&#xff1a;混合架构的设计动机 2、LSTM 的时序特征提取&#xff1a;从原始序列到高阶表征 2.1、门控机制的时序过滤能力 2.2、隐藏状态的特征压缩作用 2.3、预训练的特征优化逻辑 3、SVM 的非线性映射&#xff1a;从高阶特征到预测输出 3.1、…

如何查看docker实例是否挂载目录,以及挂载了哪些目录

一条命令即可一次性列出当前容器里所有挂载点&#xff1a; docker inspect <容器ID或名称> --format{{range .Mounts}}{{printf "%-8s %-35s -> %s\n" .Type .Source .Destination}}{{end}}示例输出&#xff1a; bind /host/owrt/src …

Opentrons 模块化平台与AI技术助力智能移液创新,赋能AAW™自动化工作站

在生命科学领域加速拥抱自动化的关键节点&#xff0c;全球开源实验室自动化领导者 Opentrons 携手全球领先生命科学公司默克生命科学&#xff0c;重磅推出 AAW™智能自动化液体处理平台。这一战略合作的核心技术引擎 ——Opentrons Flex 第三代全自动移液工作站&#xff0c;正以…

C++学习笔记(八:函数与变量)

往篇内容&#xff1a; C学习笔记&#xff08;一&#xff09; 一、C编译阶段※ 二、入门案例解析 三、命名空间详解 四、C程序结构 C学习笔记&#xff08;二&#xff09; 五、函数基础 六、标识符 七、数据类型 补充&#xff1a;二进制相关的概念 sizeof 运算符简介 补…

智慧施工:施工流程可视化管理系统

图扑智慧施工全流程可视化管理系统&#xff0c;通过可视化界面&#xff0c;可直观掌握各工序衔接进度、资源调配情况&#xff0c;快速识别违规作业、设备故障等风险点 —— 如塔吊运行半径重叠、深基坑支护位移预警等。同时&#xff0c;系统支持施工方案模拟推演&#xff0c;对…

单链表的冒泡排序实现:从原理到代码详解

单链表的冒泡排序实现&#xff1a;从原理到代码详解 引言 单链表作为一种常见的数据结构&#xff0c;其排序操作因节点无法随机访问&#xff08;需通过指针遍历&#xff09;而与数组排序存在差异。冒泡排序因其实现简单、无需额外空间&#xff08;仅需指针操作&#xff09;&…

如何在 Ubuntu 24.04 或 22.04 上安装和使用 GDebi

APT 是 Ubuntu 上安装需要外部依赖项的 Debian 包的一种方式,但还有另一种选择,即 GDebi。本文将介绍如何在 Ubuntu 24.04 上安装 GDebi,以及如何使用它来安装 .deb 包所需的依赖项。 什么是 GDebi? GDebi 是默认的 .deb 包安装器 DPKG 的轻量级替代品。与 DPKG 不同,GD…

俄罗斯方块游戏开发(面向对象编程)

摘要本设计基于MATLAB面向对象编程技术&#xff0c;开发了一款具备完整游戏逻辑的俄罗斯方块游戏。通过类封装实现游戏核心模块&#xff08;方块管理、游戏板状态、碰撞检测等&#xff09;&#xff0c;采用旋转矩阵实现方块变形&#xff0c;结合MATLAB图形用户界面&#xff08;…

背包DP之多重背包

背包DP之多重背包一、多重背包基础认知1.1 问题定义1.2 核心特征二、基础解法&#xff1a;暴力拆分2.1 核心思路2.2 代码实现2.3 局限性分析三、优化解法&#xff1a;二进制拆分3.1 优化原理3.2 拆分步骤3.3 代码实现3.4 复杂度分析四、二进制拆分过程五、多重背包的变种与应用…

Ansible 变量指南:声明、优先级、作用域与最佳实践(一)

Ansible 变量的声明 前言 全面理解 Ansible 变量是编写高效、可维护 Playbook 的关键。由于最近使用 Ansible 比较多&#xff0c;在变量问题上踩了不少坑&#xff0c;也因此对变量的声明&#xff0c;优先级和作用域有了更深的理解。姑且总结一下&#xff0c;分享给大家&#…