构建高效持久层:深度解析 MyBatis-Plus(02)
目录
- 引言
- 1. 逻辑删除
- 1.1 概述
- 1.2 逻辑删除的优势
- 1.3.为什么使用逻辑删除
- 1.4 综合案例
- 2. 乐观锁和悲观锁
- 2.1.什么是乐观锁和悲观锁
- 2.2.乐观锁和悲观锁的区别
- 2.3.综合案例
- 3. 分页插件
- 总结
引言
在现代软件开发中,数据库操作是不可或缺的一环。为了提高系统的性能、安全性以及数据一致性,开发者需要深入了解一些高级的数据库操作技术。本篇博客将深入探讨三个重要的数据库操作技术:逻辑删除、乐观锁和分页插件。通过深度讲解这些技术,读者将能够更好地应对实际项目中的复杂场景。
1. 逻辑删除
1.1 概述
MyBatis-Plus
中的逻辑删除(Logical Delete)是在数据库中进行虚拟删除,即实际删除数据时,并不会将数据从数据库中删除,而是通过一个标记来记录其已被删除。这种删除方式称为逻辑删除或软删除。
1.2 逻辑删除的优势
逻辑删除相比物理删除具有以下优势:
数据恢复: 可以方便地通过修改记录的状态来实现数据的恢复,而无需进行繁琐的数据库恢复操作。
历史记录: 可以保留数据删除的历史记录,方便日后审计和分析。
1.3.为什么使用逻辑删除
当我们使用物理删除时,数据将被永久删除,无法恢复。但有些情况下,我们并不希望永久删除数据,比如用户误删除、操作失误等情况,这时逻辑删除就尤为重要。
另外,逻辑删除还可以对应业务层逻辑,将数据状态标志为“已删除”,便于后续查询和统计。同时,逻辑删除还能提高删除操作效率,减少物理删除数据对系统性能的影响。
1.4 综合案例
配置yml
global-config:db-config:logic-delete-field: state# 全局逻辑删除的实体字段名 logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
数据表增加字段state
实体类添加对应的字段state(与yml的要一致!)
@TableField()private intstate;
此时使用mybatisplus删除就会把state从0变为1,之后查询只会显示未0的
id为1的state字段0改为1
此时id为1已经逻辑删除掉了
2. 乐观锁和悲观锁
2.1.什么是乐观锁和悲观锁
乐观锁( Optimistic Locking )和悲观锁是数据库中的两种并发控制机制。
乐观锁假定数据一般情况下不会发生冲突,因此在读取数据时不会对其加锁,而是在写入时先比较数据版本号(比如时间戳)是否相同,再进行操作。如果版本号相同,则表示该数据没有被其他进程修改,可以进行写操作;如果版本号不同,则表示该数据已经被其他进程修改,写操作会失败,需要重新读取数据进行操作。
乐观锁是为了解决并发过程中数据更新冲突的问题,乐观锁能提高并发过程中的程序吞吐量。
悲观锁则假定数据会发生冲突,因此在读取数据时就会对其加锁,防止其他进程同时修改此数据,直到当前进程操作完成并解锁后,其他进程才能再次操作该数据。
2.2.乐观锁和悲观锁的区别
乐观锁和悲观锁的区别主要有以下几点:
- 加锁时间不同:乐观锁在读取数据时不会对其加锁,而是在写入时进行比较和加锁操作;悲观锁在读取数据时就会对其加锁。
- 冲突处理方式不同:乐观锁会在写入时进行比较和冲突检测,如果版本号不一致则操作失败,需要重新读取数据;悲观锁则会阻塞其他进程对该数据的访问,直到当前进程完成操作并解锁。
- 适用场景不同:乐观锁适用于并发量比较小、数据量比较大、操作更多为读取的场景;悲观锁适用于并发量比较大、数据量比较小、操作更多为写入的场景。
总的来说,乐观锁适用于并发冲突较少的场景,可以提高系统的并发性;悲观锁适用于并发冲突较多的场景,可以保证数据的一致性和安全性。
2.3.综合案例
使用数据版本(Version)记录机制实现乐观锁,这是乐观锁最常用的一种实现方式。
在表中添加一个version字段,默认值为1
实体类上添加@Version注解
@Versionprivate Integer version;
导入插件
package com.yuan.ttx.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;// Spring Boot 方式
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}
}
然后Controller中
这个是可行的,先查询在修改,然后version+1+1
上面代码就被乐观锁锁住了,对同一个对象操作,查询后没修改,又查询,再修改,此时Version没有进行+1,任然是2然后最后的结果是第一个成功,第二个不成功
3. 分页插件
在类中添加下面代码
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
package com.yuan.ttx.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;// Spring Boot 方式
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());return mybatisPlusInterceptor;}
}
使用
@RequestMapping("/sel")public Object sel(Long p){Page<Book> page1 = new Page<>(p,5);Page<Book> res = iBookService.page(page1);return res.getRecords();}
第二页的数据
用QueryWrapper带条件查询分页
@RequestMapping("/sel")public Object sel(Long p,String name){QueryWrapper<Book> wrapper = new QueryWrapper<>();wrapper.like(StringUtils.isNotEmpty(name),"bookname",name);Page<Book> page1 = new Page<>(p,5);Page<Book> res = iBookService.page(page1,wrapper);return res.getRecords();}
总结
通过本篇博客的学习,读者深入了解了逻辑删除、乐观锁和分页插件这三个高级数据库操作技术。逻辑删除为数据的保留和恢复提供了便捷的方式,乐观锁解决了高并发场景下的数据一致性问题,而分页插件使得处理大数据集合更为高效。在实际项目中,灵活运用这些技术将使系统更加稳健、高效。
相关文章:
构建高效持久层:深度解析 MyBatis-Plus(02)
目录 引言1. 逻辑删除1.1 概述1.2 逻辑删除的优势1.3.为什么使用逻辑删除1.4 综合案例 2. 乐观锁和悲观锁2.1.什么是乐观锁和悲观锁2.2.乐观锁和悲观锁的区别2.3.综合案例 3. 分页插件总结 引言 在现代软件开发中,数据库操作是不可或缺的一环。为了提高系统的性能、…...
Gitlab仓库推送到Gitee仓库的一种思路
文章目录 Gitlab仓库推送到Gitee仓库的一种思路1、创建Gitee的ssh公钥(默认已有Gitlab的ssh公钥)2、添加Gitlab远程仓库地址3、添加Gitee远程仓库地址4、拉取Gitlab远程仓库指定分支到本地仓库指定分支(以test分支为例)5、推送本地…...
快速能访问服务器的文件
1、背景 访问ubuntu上的文件 2、方法 python3 -m http.server 8081 --directory /home/ NAS 共享访问协议 — NFS、SMB、FTP、WebDAV 各有何优势?http://1 Ubuntu 搭建文件服务器(Nginx)...
Diary26-Vue综合案例1-书籍购物车
Vue综合案例1-书籍购物车 案例要求: 代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewpor…...
【EasyExcel实践】万能导出,一个接口导出多张表以及任意字段(可指定字段顺序)-简化升级版
文章目录 前言正文一、项目简介二、核心代码2.1 pom.xml 依赖配置2.2 ExcelHeadMapFactory2.3 ExcelDataLinkedHashMap2.4 自定义注解 ExcelExportBean2.5 自定义注解 ExcelColumnTitle2.6 建造器接口 Builder2.7 表格工具类 ExcelUtils2.8 GsonUtil2.9 模版类 ExportDynamicCo…...
解决 Hive 外部表分隔符问题的实用指南
简介: 在使用 Hive 外部表时,分隔符设置不当可能导致数据导入和查询过程中的问题。本文将详细介绍如何解决在 Hive 外部表中正确设置分隔符的步骤。 问题描述: 在使用Hive外部表时,可能会遇到分隔符问题。这主要是因为Hive在读…...
一文学会 Apache Zeppelin
Zeppelin资料 Zeppelin项目信息 Zeppelin官网 http://zeppelin.apache.org/Zeppelin源码地址 https://github.com/apache/zeppelinZeppelin JIRA: https://issues.apache.org/jira/projects/ZEPPELIN/summaryZeppelin文档 Flink on Zeppelin 文档集中地 https://www.yuque.co…...
ROS学习笔记(七)---参数服务器
ROS学习笔记文章目录 01. ROS学习笔记(一)—Linux安装VScode 02. ROS学习笔记(二)—使用 VScode 开发 ROS 的Python程序(简例) 03. ROS学习笔记(三)—好用的终端Terminator 04. ROS学习笔记(四)—使用 VScode 启动launch文件运行多个节点 05. ROS学习笔…...
【RTOS学习】源码分析(信号量和互斥量 事件组 任务通知)
🐱作者:一只大喵咪1201 🐱专栏:《RTOS学习》 🔥格言:你只管努力,剩下的交给时间! 目录 🍓信号量和互斥量🍅创建🍅Take🍅Give &#x…...
1316:【例4.6】数的计数(Noip2001) 代码+解析
1316:【例4.6】数的计数(Noip2001) 【题目描述】 我们要求找出具有下列性质数的个数(包括输入的自然数n )。先输入一个自然数n(n≤1000),然后对此自然数按照如下方法进行处理:不作任何处理;在它的左边加上一…...
征集倒计时 | 2023年卓越影响力榜单-第四届中国产业创新奖报名即将截止
第四届「ISIG中国产业智能大会」将于2024年3月16日在上海举办。2024 ISIG 以“与科技共赢,与产业共进”为主题,共设立RPA超自动化、 低代码、AIGC大模型、流程挖掘四大主题峰会。届时,大会组委会将颁发2023年度卓越影响力榜单—第四届中国产业…...
vue的语法模板与数据绑定的说明
vue的两大模板语法: 1.插值语法 2.指定语法 插值语法:{{}} 功能:用于解析标签体的内容 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性 指定语法: 功能:用于解析标签(包括:标签属性、标…...
VueCron使用方法
1)什么是vueCron Vue Cron 是基于 Vue.js 的定时任务管理组件,它提供了一种简单易用的方式来设定和管理定时任务。Vue Cron 提供了一个类似于 Linux crontab 的界面,用户可以通过它来创建、编辑和删除定时任务。 2)安装依赖及应…...
SpringBlade export-user SQL 注入漏洞复现
0x01 产品简介 SpringBlade 是一个由商业级项目升级优化而来的 SpringCloud 分布式微服务架构、SpringBoot 单体式微服务架构并存的综合型项目。 0x02 漏洞概述 SpringBlade v3.2.0 及之前版本框架后台 export-user 路径存在安全漏洞,攻击者利用该漏洞可通过组件customSqlS…...
结构体的一些补充知识
1、结构体后面分号前面的名字是什么意思。 在C中,结构体的定义格式为: struct <结构体名> {// 成员变量和成员函数 };在这个定义中,<结构体名>就是结构体的名称,而这个名称位于结构体定义的末尾,分号之前…...
20V升26V 600mA升压型LED驱动芯片,PWM调光芯片-AH1160
AH1160是一个功能强大的升压型LED驱动芯片,专为需要精确控制LED亮度的PWM调光应用而设计。它可将20V输入电压升压至26V,同时提供稳定的600mA电流输出,适用于各种LED照明设备。 芯片特点: 1. 输入电压范围:AH1160可在…...
如何在Go中制作HTTP服务器
引言 许多开发人员至少会花一些时间创建服务器,以便在互联网上分发内容。HTTP (Hypertext Transfer Protocol,超文本传输协议)提供了大部分这些内容,无论是请求一张猫的图片还是请求加载你正在阅读的教程。Go标准库为创建HTTP服务器以提供web内容或向这些服务器发出HTTP请求…...
Linux笔记---系统信息
🍎个人博客:个人主页 🏆个人专栏:Linux学习 ⛳️ 功不唐捐,玉汝于成 目录 前言 命令 1. uname - 显示系统信息 2. hostname - 显示或设置系统主机名 3. top - 显示系统资源使用情况 4. df - 显示磁盘空间使用情…...
最新版android stuido加上namespace
每个 Android 模块都有一个命名空间,此命名空间用作其生成的 命名空间由模块的 build.gradle 文件中的 namespace 属性定义,如以下代码段所示。namespace 最初会设为您在创建项目时选择的软件包名称。 Kotlin Groovy android {namespace "com.ex…...
Wireshark基础及捕获技巧
第一章:Wireshark基础及捕获技巧 1.1 Wireshark基础知识回顾 1.2 高级捕获技巧:过滤器和捕获选项 1.3 Wireshark与其他抓包工具的比较 第二章:网络协议分析 2.1 网络协议分析:TCP、UDP、ICMP等 2.2 高级协议分析:HTTP…...
Windows下Navicat15.0连接Oracle11g报ORA-28547解决
目录 背景 一、相关环境 1、操作系统 2、Navicat版本 3、ORACLE连接 4、默认连接 二、问题分析 1、默认dll配置 三、修改配置 1、下载匹配的client 2、替换相应目录 总结 背景 最近在项目中需要使用Oracle数据库,当前很多应用系统的数据都存储在MySQL或者Pos…...
21 Vue3中使用v-for遍历对象数组
概述 使用v-for遍历对象数组在真实的开发中也属于非常常见的用法,需要重点掌握。 因为目前流行的是前后端分离开发,在前后端分离开发中,最常需要处理的就是对象数组类型的数据了。 比如,将员工信息渲染到表格中。 这节课我们就…...
深入理解Java自定义异常与全局异常处理 @RestControllerAdvice
异常主要是包括编译时的异常和运行时的异常。编译时的异常可以通过捕获异常获取,运行时候的异常主要是通过代码规范,或者测试。 Spring Boot提供了两种异常处理方式来统一处理和维护异常信息。 第一种方式是使用RestControllerAdvice注解与ExceptionHand…...
h5页面跳转微信小程序(最简单的方法|URL Scheme)
文章目录 导文实现获取 URL Scheme加密 URL Scheme获取方式拼接参数 明文 URL Scheme获取方式 实际项目展示:频率限制注意事项开放范围示例代码包 导文 H5页面跳转微信小程序的需求是普遍存在的。由于微信小程序是一种只能在微信内部访问的应用程序,而H5…...
智能优化算法应用:基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.非洲秃鹫算法4.实验参数设定5.算法结果6.…...
持续集成交付CICD:Jenkins使用GitLab共享库实现前端项目镜像构建
目录 一、实验 1. GitLab修改项目文件与Harbor环境确认 2.Jenkins使用GitLab共享库实现前端项目镜像构建 3.优化CI流水线封装Harbor账户密码 4.Jenkins再次使用GitLab共享库实现前端项目镜像构建 一、实验 1. GitLab修改项目文件与Harbor环境确认 (1…...
SQL server 数据库 SQL语句高级用法
1、表的高级查询 use student select * from stuinfo1 -- 使用 in 的子查询 select * from stuinfo where stu_age in ( select stu_age from stuinfo where cla_id 12345 ) select * from stuinfo where stu_age in ( 19 , 20 , 21 , 25 , 23 , 1…...
wavlink 路由器 多处前台RCE漏洞复现
0x01 产品简介 WAVLINK是中国睿因科技(WAVLINK)公司开发的一款路由器。 0x02 漏洞概述 WAVLINK路由器mesh.cgi、nightled.cgi、live-api.cgi等接口处存在命令执行漏洞,攻击者可通过该漏洞获取服务器权限。包含型号WN530HG4、WN531G3、WN572HG3、WN535G3、WN575A4等。 0x…...
互联网中的商品超卖问题及其解决方案:Java中Redis结合UUID的应用
前言 在设计商品下单和库存扣减,你一定遇到过这样的问题,库存扣减为0了,可是消费者还能下单,并将订单信息保存到了数据库里,针对商品超卖问题,作此篇以解决。 随着互联网商业的飞速发展,商品超…...
mysql:查看线程缓存中的线程数量
使用命令show global status like Threads_cached;可以查看线程缓存中的线程数量。 例如,查询线程缓存中的线程数量如下: 然后启动应用程序,使用连接,查询如下: 由查询结果可以看到,线程缓存中的线程数量…...
wordpress登陆可见插件/整站优化外包服务
C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。 内存映射文件对于托管世界的开发人员来说似乎很陌生,但它…...
企业为什么融资/seo优化内容
一、什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用。 下面我们就对OGNL这5个作用进行讲解 1、存取对象的任意属性,简单说就是对javabean进行操作(重要) 2、调用对象方法。 3、调用类的静态方法 4、索引数组元素 5、操作集…...
做网站没签合同/百度惠生活商家入驻
图的邻接表存储 代码如下: //图的邻接表存储结构#include<stdio.h> #include<string.h> #include<malloc.h> #define MAX_VERTEX_NUM 20 //最大顶点个数 #define MAX_NAME 3 //顶点字符串最大长度1 #define ERROR 0 #define OK …...
最新的疫情最新消息/seo文章范文
上一篇讲了界面的实现,详情请戳Android利用Cookie实现码源登录效果(一) - 界面实现,本篇将对功能的实现进行分析。 具体实现 功能实现 使用HttpClient进行post请求 在进行post请求的时候,我们先看看网页版登录是如何发…...
wordpress缩略图模糊/工具大全
在VMware里克隆出来的CentOS Linux,ifconfig...没有看到eth0,然后重启网卡又报下面错误。 故障现象: service network restartShutting down loopback insterface: …...
莆田网站制作/百度排名点击软件
计算原理:根据勾股定理算两个坐标直线距离 java版本 package com.application.util;/*** 地图坐标距离计算**/ public class LocationUtils {private static double EARTH_RADIUS 6378.137;private static double rad(double d) {return d * Math.PI / 180.0;}/***…...