MybatisPlus(一)扩展功能

扩展功能

  • 一、静态工具
  • 二、逻辑删除
  • 三、通用枚举
    • 1、定义枚举
    • 2、配置枚举处理器
    • 3、测试
  • 四、JSON类型处理器
    • 1、定义实体
    • 2、使用类型处理器
  • 五、分页
    • 1、配置分页插件
    • 2、分页API
    • 3、示例

一、静态工具

有的时候Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db,其中的一些静态方法与IService中方法签名基本一致,也可以帮助我们实现CRUD功能:
在这里插入图片描述
实例:

@Test
void testDbGet() {User user = Db.getById(1L, User.class);System.out.println(user);
}@Test
void testDbList() {// 利用Db实现复杂条件查询List<User> list = Db.lambdaQuery(User.class).like(User::getUsername, "o").ge(User::getBalance, 1000).list();list.forEach(System.out::println);
}@Test
void testDbUpdate() {Db.lambdaUpdate(User.class).set(User::getBalance, 2000).eq(User::getUsername, "Rose");
}

传入实体类的class字节码,拿到字节码就能通过反射拿到实体类的相关信息,从而拿到注解上的信息诸如类名、表名等,以此实现CURD。
Db静态类其实很原始service的方法使用基本一致,只是多了一个实体类的class字节码。

二、逻辑删除

对于一些比较重要的数据,我们往往会采用逻辑删除的方案,即:

  • 在表中添加一个字段标记数据是否被删除
  • 当删除数据时把标记置为true
  • 查询时过滤掉标记为true的数据
    一旦采用了逻辑删除,所有的查询和删除逻辑都要跟着变化,非常麻烦。

为了解决这个问题,MybatisPlus就添加了对逻辑删除的支持。

只有MybatisPlus生成的SQL语句才支持自动的逻辑删除,自定义SQL需要自己手动处理逻辑删除。

例如,我们给address表添加一个逻辑删除字段:

alter table address add deleted bit default b'0' null comment '逻辑删除';

然后给Address实体添加deleted字段:
在这里插入图片描述

接下来,我们要在application.yml中配置逻辑删除字段:

mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

测试:
首先,我们执行一个删除操作:

@Test
void testDeleteByLogic() {// 删除方法与以前没有区别addressService.removeById(59L);
}

方法与普通删除一模一样,但是底层的SQL逻辑变了:
在这里插入图片描述
查询一下试试:

@Test
void testQuery() {List<Address> list = addressService.list();list.forEach(System.out::println);
}

会发现id为59的确实没有查询出来,而且SQL中也对逻辑删除字段做了判断:
在这里插入图片描述

综上, 开启了逻辑删除功能以后,我们就可以像普通删除一样做CRUD,基本不用考虑代码逻辑问题。还是非常方便的。
注意:
逻辑删除本身也有自己的问题,比如:

  • 会导致数据库表垃圾数据越来越多,从而影响查询效率
  • SQL中全都需要对逻辑删除字段做判断,影响查询效率

因此,我不太推荐采用逻辑删除功能,如果数据不能删除,可以采用把数据迁移到其它表的办法。

三、通用枚举

User类中有一个用户状态字段:
在这里插入图片描述

像这种字段我们一般会定义一个枚举,做业务判断的时候就可以直接基于枚举做比较。但是我们数据库采用的是int类型,对应的PO也是Integer。因此业务操作时必须手动把枚举与Integer转换,非常麻烦。
因此,MybatisPlus提供了一个处理枚举的类型转换器,可以帮我们把枚举类型与数据库类型自动转换。

1、定义枚举

我们定义一个用户状态的枚举:
在这里插入图片描述

package com.itheima.mp.enums;import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;@Getter
public enum UserStatus {NORMAL(1, "正常"),FREEZE(2, "冻结");private final int value;private final String desc;UserStatus(int value, String desc) {this.value = value;this.desc = desc;}
}

然后把User类中的status字段改为UserStatus 类型:
在这里插入图片描述

要让MybatisPlus处理枚举与数据库类型自动转换,我们必须告诉MybatisPlus,枚举中的哪个字段的值作为数据库值。
MybatisPlus提供了@EnumValue 注解来标记枚举属性:
在这里插入图片描述

2、配置枚举处理器

在application.yaml文件中添加配置:

mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

3、测试

@Test
void testService() {List<User> list = userService.list();list.forEach(System.out::println);
}

在这里插入图片描述
同时,为了使页面查询结果也是枚举格式,我们需要修改UserVO中的status属性:

在这里插入图片描述
并且,在UserStatus枚举中通过@JsonValue注解标记JSON序列化时展示的字段:

在这里插入图片描述

最后,在页面查询,结果如下:

在这里插入图片描述

四、JSON类型处理器

数据库的user表中有一个info字段,是JSON类型:
在这里插入图片描述

格式像这样:

{"age": 20, "intro": "佛系青年", "gender": "male"}

而目前User实体类中却是String类型:
在这里插入图片描述

这样一来,我们要读取info中的属性时就非常不方便。如果要方便获取,info的类型最好是一个Map或者实体类。

而一旦我们把info改为对象类型,就需要在写入数据库时手动转为String,再读取数据库时,手动转换为对象,这会非常麻烦。

因此MybatisPlus提供了很多特殊类型字段的类型处理器,解决特殊字段类型与数据库类型转换的问题。例如处理JSON就可以使用JacksonTypeHandler处理器。

1、定义实体

我们定义一个单独实体类来与info字段的属性匹配:

package com.itheima.mp.domain.po;import lombok.Data;@Data
public class UserInfo {private Integer age;private String intro;private String gender;
}

2、使用类型处理器

接下来,将User类的info字段修改为UserInfo类型,并声明类型处理器:
在这里插入图片描述
同时,在User类上添加一个注解,声明自动映射:

在这里插入图片描述

测试可以发现,所有数据都正确封装到UserInfo当中了:

在这里插入图片描述

五、分页

在未引入分页插件的情况下,MybatisPlus是不支持分页功能的,IService和BaseMapper中的分页方法都无法正常起效。
所以,我们必须配置分页插件。

1、配置分页插件

在项目中新建一个配置类:
在这里插入图片描述

其代码如下:

package com.itheima.mp.config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MybatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 初始化核心插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 添加分页插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

2、分页API

编写一个分页查询的测试:

@Test
void testPageQuery() {// 1.分页查询,new Page()的两个参数分别是:页码、每页大小Page<User> p = userService.page(new Page<>(2, 2));// 2.总条数System.out.println("total = " + p.getTotal());// 3.总页数System.out.println("pages = " + p.getPages());// 4.数据List<User> records = p.getRecords();records.forEach(System.out::println);
}

在这里插入图片描述
这里用到了分页参数,Page,即可以支持分页参数,也可以支持排序参数。常见的API如下:

int pageNo = 1, pageSize = 5;
// 分页参数
Page<User> page = Page.of(pageNo, pageSize);
// 排序参数, 通过OrderItem来指定
page.addOrder(new OrderItem("balance", false));userService.page(page);

3、示例

现在要实现一个用户分页查询的接口,接口规范如下:
在这里插入图片描述

controller.java

package com.itheima.mp.controller;import com.itheima.mp.domain.dto.PageDTO;
import com.itheima.mp.domain.query.PageQuery;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("users")
@RequiredArgsConstructor
public class UserController {private final UserService userService;@GetMapping("/page")public PageDTO<UserVO> queryUsersPage(UserQuery query){return userService.queryUsersPage(query);}// 。。。 略
}

然后在IUserService中创建queryUsersPage方法:

PageDTO<UserVO> queryUsersPage(PageQuery query);

接下来,在UserServiceImpl中实现该方法:

@Override
public PageDTO<UserVO> queryUsersPage(PageQuery query) {// 1.构建条件// 1.1.分页条件Page<User> page = Page.of(query.getPageNo(), query.getPageSize());// 1.2.排序条件if (query.getSortBy() != null) {page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));}else{// 默认按照更新时间排序page.addOrder(new OrderItem("update_time", false));}// 2.查询page(page);// 3.数据非空校验List<User> records = page.getRecords();if (records == null || records.size() <= 0) {// 无数据,返回空结果return new PageDTO<>(page.getTotal(), page.getPages(), Collections.emptyList());}// 4.有数据,转换List<UserVO> list = BeanUtil.copyToList(records, UserVO.class);// 5.封装返回return new PageDTO<UserVO>(page.getTotal(), page.getPages(), list);
}

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

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

相关文章

Redis哨兵模式之Sentinel模式(二)

一、多节点哨兵如何配置&#xff1f; 哨兵配置原理图 注意&#xff1a;sentinel哨兵模式的搭建是建立在redis主从复制节点配置基础而搭建&#xff0c;在主从配置中从库需要配置好replicaof关联上主库并关闭安全模式&#xff0c;然后设置好bind端口才能关联上机器&#xff0c;而…

基于Excel的数据分析思维与分析方法

数据分析一定要会Excel、SQL和Python&#xff1f;非常肯定地回答您&#xff0c;Python、R语言、Excel函数和VBA&#xff0c;以及高级数据分析软件&#xff0c;都学不到&#xff0c;您将学到&#xff1a;5个有效的数据分析利器&#xff0c;以及分析思维 一、描述性统计分析 在…

计算机网络笔记(不全)

一、计算机网络体系结构1.计算机网络的概念计算机网络&#xff1a;由若干结点和连接这些结点的链路组成。结点可以是计算机、集线器、交换机、路由器等。互连网(internet)&#xff1a;多个计算机网络通过路由器互相连接而成&#xff0c;可用任意协议通信。互联网(因特网Interne…

XML Schema 复合元素

XML Schema 复合元素 引言 XML(可扩展标记语言)作为一种灵活的标记语言,广泛应用于数据交换和存储。XML Schema 是一种用于描述和定义 XML 文档结构的语言,它定义了 XML 文档的元素、属性、类型和约束。本文将详细介绍 XML Schema 中的复合元素,并探讨其在实际应用中的重…

华为云Flexus+DeepSeek征文 | 弹性算力实战:Flexus X实例自动扩缩容策略优化

华为云FlexusDeepSeek征文 | 弹性算力实战&#xff1a;Flexus X实例自动扩缩容策略优化 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 总有一行代码&#xff0c;能点亮万千星辰。 &#x1f50d; 在技术的宇宙中&#xff0c;我愿做永不停歇的探索者…

【仓颉】运行环境配置VSCode + Win11

作者&#xff1a;大李子 团队&#xff1a;坚果派 十年iOS&#xff0c;All in转鸿蒙 前言 “仓颉编程语言是一款面向全场景智能的新一代编程语言&#xff0c;主打原生智能化、天生全场景、高性能、强安全。融入鸿蒙生态&#xff0c;为开发者提供良好的编程体验。” ——摘自仓…

【K线训练软件研发历程】【日常记录向】1.K线滑动窗口

文章目录 当前效果未来发展思路技术选型值得分享的技术点数据加载、解析的代码echats的代码当前效果 👆相当于有个hello world了。 未来发展思路 开源 技术选型 界面直接采用electron,等开源后,可以直接挂release,用户下载安装包后,一键安装,一键运行,降低使用门槛…

抖音解析下载工具 v1.0.0:免安装单文件,一键无水印保存高清视音频

宝子们&#xff0c;今天给你们带来一款超轻量的抖音下载神器——抖音解析下载工具 v1.0.0。 它只有单文件&#xff0c;双击就能用&#xff0c;免安装、无广告、完全免费&#xff0c;复制粘贴链接即可一键解析下载高清无水印视频/音频&#xff0c;简直不要太方便&#xff01; 为…

Ingress——2

目录 ‌一. 域名重定向&#xff08;HTTP→HTTPS/旧域名跳转&#xff09;‌ ‌二. 前后端分离Rewrite&#xff08;路径改写&#xff09;‌ ‌三. 混合配置示例&#xff08;重定向Rewrite&#xff09;‌ ‌四. SSL/TLS配置&#xff08;HTTPS加密&#xff09;‌ ‌五. 基本认…

12. grafana-Dashboard的Variable(过滤)使用

说明制作这样一个选择过滤的下拉框&#xff0c;可以选择某个服务器的步骤1. 点击最上面的Dashboard settings2. 选择Variables 并点击ADD variable3. 写出过滤的标签名和查询条件&#xff08;label_values(查询条件)&#xff09;4. 点击 save as... 保存退出5. 出来后左上角就…

Cursor一键续杯pro教程,支持最新1.0系列版本

使用前检查&#xff1a; 使用前请先看左下角&#xff0c;是否获取到Cursor的版本号 如果没有请先在 功能页面 -→ 自定义Cursor路径 选择你Cursor的安装的路径&#xff0c;并开启后重启YCursor&#xff0c;获取到版本后才能正常使用功能 检查软件左下角的权限标识是否为绿色 如…

pyhton基础【25】面向对象进阶六

目录 十七.单例模式 实现单例模式的两种方式 __new__方法概述 单例模式的使用场景 十七.单例模式 引入 单例模式是一种常用的软件设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取这个实例。 实现单例模式的两种方式 使用类属性创…

后端树形结构

案例 在后端开发中&#xff0c;树形结构数据的查询和处理是一个常见的需求&#xff0c;比如部门管理、分类目录展示等场景。接下来&#xff0c;我们以一个部门管理系统为例&#xff0c;详细介绍如何实现后端的树查询功能。 案例背景 假设我们正在开发一个公司的内部管理系统&am…

高效沟通04-RIDE说服模型

高效沟通专栏–组织运转的命脉与个人成功的基石 目录 1. RIDE模型的核心理念2. RIDE模型的应用场景3. RIDE模型使用步骤4. RIDE模型示例与练习4.1 应用RIDE模型:4.2 练习:你来试试!5. 总结RIDE模型是一种结构化的说服框架,旨在帮助你在沟通(尤其是书面沟通或需要清晰逻辑…

利用selenium获取网页数据,脚本加载慢问题的解决办法

问题&#xff1a;最近在写一个脚本去获取一个网站的数据&#xff0c;用到一个表格中的数据&#xff0c;条目是1000条&#xff0c;需要逐条去获取网站上对应的数据&#xff0c;遇到的问题是脚本运行后&#xff0c;很久才开始打开驱动浏览器。经过很多次尝试&#xff0c;主要原因…

Ubuntu查看本机代理的实操指南

快速确认代理状态的必要性在Ubuntu系统中&#xff0c;代理设置是跨境访问、企业内网连接、开发调试的重要配置。无论是排查网络卡顿、验证代理是否生效&#xff0c;还是确保特定应用走代理通道&#xff0c;快速查看当前代理状态都是关键步骤。图形界面查看&#xff0c;可视化操…

三格电子——双通道 CAN(FD)转以太网

【SG-CAN(FD)NET-210】 一、功能描述 CANFD 完全向下兼容 CAN &#xff0c;以下统称 CAN(FD) 。 SG-CAN(FD)NET-210 是一款用来把 CANFD 总线数据转为网口数据的设 备。 网口支持 TCP Sever 、 TCP Client 、 UDP Sever 、 UDP Client 四种模式。 可以通过软件配置…

【一起来学AI大模型】卷积神经网络(CNN):视觉识别的革命性架构

一、CNN的核心思想与生物启示 卷积神经网络&#xff08;Convolutional Neural Networks&#xff09;是受生物视觉皮层启发的深度学习架构&#xff0c;专门用于处理网格状拓扑数据&#xff08;如图像、视频、音频&#xff09;。其核心创新在于&#xff1a; 局部感受野&#xff…

创建和编辑Crontab的方法

计划任务&#xff0c;在 Linux 中一般使用Crontab&#xff0c;通过crontab命令&#xff0c;我们可以在固定的间隔时间执行指定的系统指令或 Shell 脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令非常适合周期性的日志分析或数据备份等工作。 创建…

在职场中如何培养创新思维?

芯片研发人员&#xff0c;授权发明专利40&#xff0c;聊聊技术层面的创新&#xff0c; 创新的本质&#xff0c;是旧有知识的创造性组合&#xff0c; 不存在无中生有的创新&#xff0c; 你必须建立本领域的知识体系&#xff0c;对过往各种创新&#xff0c;烂熟于心&#xff0…