04 MyBatisPlus之逻辑删除+锁+防全表更新/删除+代码生成插件

1 逻辑删除

1. 1 什么是逻辑删除 , 以及逻辑删除和物理删除的区别?

逻辑删除,可以方便地实现对数据库记录的逻辑删除而不是物理删除。逻辑删除是指通过更改记录的状态或添加标记字段来模拟删除操作,从而保留了删除前的数据,便于后续的数据分析和恢复。

  • 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
  • 逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录。
    因此说,逻辑删除不是真正的删除语句 , 其实质是更新逻辑删除字段的更新语句!

1.2 逻辑删除实现:

1.2.1 数据库和实体类添加逻辑删除字段

1.2.1.1 表添加逻辑删除字段,可以是一个布尔类型、整数类型或枚举类型。用来指示是否已经逻辑删除
ALTER TABLE USER ADD deleted INT DEFAULT 0 ;  # int 类型 1 逻辑删除 0 未逻辑删除
1.2.1.2 实体类添加逻辑删除属性,属性之上增加逻辑删除注解

实体类中指定逻辑删除字段的方法
a. 单一指定

@Data
public class User {

   // @TableId
    private Integer id;
    private String username;
    private Integer age;
     @TableLogic
    // 注解之下的属性就是判断是否已经逻辑删除的状态字段
    //当删除数据时,语句自动变更为修改该列的值。默认0 未删除 1 已删除
    //查询数据时,默认只查询逻辑删除字段为0(未删除)的数据
    private Integer deleted;
}

b. 全局指定

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)
  1. 演示逻辑删除操作
//逻辑删除
@Test
public void testQuick5(){
    //逻辑删除
    userMapper.deleteById(5);
}

执行效果:

   JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5871a482] will not be managed by Spring
==> Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0
==> Parameters: 5(Integer)
<==    Updates: 1
  1. 测试查询数据
@Test
public void testQuick6(){
    //正常查询.默认查询非逻辑删除数据
    userMapper.selectList(null);
}

//SELECT id,name,age,email,deleted FROM user WHERE deleted=0

2 乐观锁

对数据库的并发操作可能导致一些问题:
在这里插入图片描述

**解决思路: **

  • 悲观锁:

悲观锁的基本思想是,在整个数据访问过程中,将共享资源锁定,以确保其他线程或进程不能同时访问和修改该资源。悲观锁的核心思想是"先保护,再修改"。在悲观锁的应用中,线程在访问共享资源之前会获取到锁,并在整个操作过程中保持锁的状态,阻塞其他线程的访问。只有当前线程完成操作后,才会释放锁,让其他线程继续操作资源。这种锁机制可以确保资源独占性和数据的一致性,但是在高并发环境下,悲观锁的效率相对较低。

  • 乐观锁:

乐观锁的基本思想是,认为并发冲突的概率较低,因此不需要提前加锁,而是在数据更新阶段进行冲突检测和处理。乐观锁的核心思想是"先修改,后校验"。在乐观锁的应用中,线程在读取共享资源时不会加锁,而是记录特定的版本信息。当线程准备更新资源时,会先检查该资源的版本信息是否与之前读取的版本信息一致,如果一致则执行更新操作,否则说明有其他线程修改了该资源,需要进行相应的冲突处理。乐观锁通过避免加锁操作,提高了系统的并发性能和吞吐量,但是在并发冲突较为频繁的情况下,乐观锁会导致较多的冲突处理和重试操作。

理解点: 悲观锁和乐观锁是两种解决并发数据问题的思路,不是具体技术!!!

具体技术和方案:

  1. 乐观锁实现方案和技术:
    • 版本号/时间戳:为数据添加一个版本号或时间戳字段,每次更新数据时,比较当前版本号或时间戳与期望值是否一致,若一致则更新成功,否则表示数据已被修改,需要进行冲突处理。
    • CAS(Compare-and-Swap):使用原子操作比较当前值与旧值是否一致,若一致则进行更新操作,否则重新尝试。
    • 无锁数据结构:采用无锁数据结构,如无锁队列、无锁哈希表等,通过使用原子操作实现并发安全。
  2. 悲观锁实现方案和技术:
    • 锁机制:使用传统的锁机制,如互斥锁(Mutex Lock)或读写锁(Read-Write Lock)来保证对共享资源的独占访问。
    • 数据库锁:在数据库层面使用行级锁或表级锁来控制并发访问。
    • 信号量(Semaphore):使用信号量来限制对资源的并发访问。

介绍版本号乐观锁技术的实现流程:

  • 每条数据添加一个版本号字段version
  • 取出记录时,获取当前 version
  • 更新时,检查获取版本号是不是数据库当前最新版本号
  • 如果是[证明没有人修改数据], 执行更新, set 数据更新 , version = version+ 1
  • 如果 version 不对[证明有人已经修改了],我们现在的其他记录就是失效数据!就更新失败
3.2.2 使用mybatis-plus数据使用乐观锁
  1. 添加乐观锁拦截器
package com.sunplanter.Main
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    //将乐观锁拦截器加入大拦截器中,今后每次项目运行都会自动初始化大拦截器
    //MP会在每次更新都对比新旧版本号
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}
  1. 实体类的乐观锁字段添加@Version注解 , 数据库添加version字段
ALTER TABLE USER ADD VERSION INT DEFAULT 1 ;  # int 类型 乐观锁字段
      - 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
      - 仅支持 `updateById(id)``update(entity, wrapper)` 方法
@Version
private Integer version;
  1. 每次更新前先查询 , 以获取旧的version,待稍后修改时对比新的version
//演示乐观锁生效场景
@Test
public void testQuick7(){
    //步骤1: 先查询,在更新 获取version数据
    //同时查询两条,但是version唯一,最后更新的失败
    User user  = userMapper.selectById(5);
    User user1  = userMapper.selectById(5);

    user.setAge(20);
    user1.setAge(30);

    userMapper.updateById(user);
    //乐观锁生效,失败!
    userMapper.updateById(user1);
}

3.3 防全表更新和删除实现

针对 update 和 delete 语句 作用: 阻止恶意的全表更新删除

添加防止全表更新和删除拦截器

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
  MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
  return interceptor;
}
}

测试全部更新或者删除

@Test
public void testQuick8(){
    User user = new User();
    user.setName("custom_name");
    user.setEmail("xxx@mail.com");
    //Caused by: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of table update operation
    //全局更新,报错
    userService.saveOrUpdate(user,null);
}

3.4 MyBatisX

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

flink operator 拉取阿里云私有镜像(其他私有类似)

创建 k8s secret kubectl --namespace flink create secret docker-registry aliyun-docker-registry --docker-serverregistry.cn-shenzhen.aliyuncs.com --docker-usernameops_acr1060896234 --docker-passwordpasswd --docker-emailDOCKER_EMAIL注意命名空间指定你使用的 我…

MeterSphere本地化部署实践

项目结构 搭建本地环境 安装JDK11&#xff0c;配置好JDK环境&#xff0c;系统同时支持JDK8和JDK11安装IEAD&#xff0c;配置JDK环境配置maven环境,IDEA配置(解压可以直接使用)无限重置IDEA试用期配置redis环境(解压可以直接使用) 配置kafka环境 安装mysql-5.7环境&#xff…

Java并发基础:一文讲清util.concurrent包的作用

java.util.concurrent包是 Java 中用于并发编程的重要工具集&#xff0c;提供了线程池、原子变量、并发集合、同步工具类、阻塞队列等一系列高级并发工具类&#xff0c;使用这些工具类可以极大地简化并发编程的难度&#xff0c;减少出错的可能性&#xff0c;提高程序的效率和可…

街机模拟游戏逆向工程(HACKROM)教程:[13]68K汇编-jmp指令

在68K汇编中&#xff0c;有多个可以改变PC寄存器的指令&#xff1a; jmp 该指令在之前的章节已经介绍&#xff0c;该指令可以把目的操作数传递到PC寄存器&#xff0c;实现程序的流程控制。 bra 该指令的作用与jmp几乎相同&#xff0c;同样可以把目的操作数传递到PC寄存器&a…

【论文阅读】ControlNet、文章作者 github 上的 discussions

文章目录 IntroductionMethodControlNetControlNet for Text-to-Image DiffusionTrainingInference Experiments消融实验定量分析 在作者 github 上的一些讨论消融实验更进一步的探索Precomputed ControlNet 加快模型推理迁移控制能力到其他 SD1.X 模型上其他 Introduction 提…

贪心算法 ——硬币兑换、区间调度、

硬币兑换&#xff1a; from book&#xff1a;挑战程序设计竞赛 思路&#xff1a;优先使用大面额兑换即可 package mainimport "fmt"func main() {results : []int{}//记录每一种数额的张数A : 620B : A//备份cnts : 0 //记录至少需要多少张nums : []int{1, 5, 10, 5…

idea中使用git提交代码报 Nothing To commit No changes detected

问题描述 在idea中右键&#xff0c;开始将变更的代码进行提交的时候&#xff0c;【Commit Directory】点击提交的时候 报 Nothing To commit No changes detected解决方案 在这里点击Test 看看是不是能下面显示git版本&#xff0c;不行的话 会显示一个 fix的字样&#xff0c;行…

专业130+总分380+哈尔滨工程大学810信号与系统考研经验水声电子信息与通信

今年专业课810信号与系统130&#xff0c;总分380顺利考上哈尔滨工程大学&#xff0c;一年的努力终于换来最后的录取&#xff0c;期中复习有得有失&#xff0c;以下总结一下自己的复习经历&#xff0c;希望对大家有帮助&#xff0c;天道酬勤&#xff0c;加油&#xff01;专业课&…

SSE[Server-Sent Events]实现页面流式数据输出(模拟ChatGPT流式输出)

文章目录 前言SSE 简介应用场景区分浏览器支撑性 实现过程Web VUE核心解析数据代码实例demo参考 前言 服务端向客户端推送消息&#xff0c;除了用WebSocket可实现&#xff0c;还有一种服务器发送事件(Server-Sent Events)简称 SSE&#xff0c;这是一种服务器端到客户端(浏览器)…

C++大学教程(第九版)5.25去除break语句 5.27去除cintinue语句

5.25题目 (去除break和continue)break和continue 语句遭到质疑的原因是它们的非结构化性。实际上,break和continue 语句总能用结构化的语句取代。请详述如何从程序的一条循环语中去除break语句&#xff0c;并用某种结构化的手段替代。提示:break 语句用于在循环体内离开一个循…

Addressables(1) 从安装到加载单个/多个资源

不想再配改那些狗屎路径&#xff0c;准备研究一下Adressable&#xff0c;据说可以用key加载指定的资源 刚安装下来&#xff0c;随便搞了个资源勾选了一下addressable的框框&#xff0c;多了好多东西啊 概念铺天盖地而来&#xff0c;ok 没事的 慢慢来&#xff01; 前置知识 P…

pytorch GPU版本安装 python windows

annanconda环境 创建虚拟环境 pytorch19_gpu create -n pytorch19_gpu python3.9 激活环境 conda activate pytorch19_gpu 查找CUDA版本是12.0&#xff0c;查找方式&#xff0c;win r输入cmd进入命令行模式&#xff0c;输入nvidia-smi&#xff0c;如下&#xff0c; 查找如…

Bit.Store 加密卡集成主流 BRC20 ,助力 BTC 生态 Token 的流动性与消费

“Bit.Store 首创性的将包括 ORDI、SATS、以及 RATS 在内的主流 BRC20 资产集成到其加密卡支付中&#xff0c;通过以其推出的加密银行卡为媒介&#xff0c;助力 BTC 生态 Token 的流动性与消费。” 比特币网络在被设计之初&#xff0c;就是以一种去中心化、点对点的现金系统为定…

【Qt】对象树与坐标系

需要云服务器等云产品来学习Linux的同学可以移步/-->腾讯云<--/-->阿里云<--/-->华为云<--/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;新用户首次下单享超低折扣。 目录 一、Qt Creator快捷键 二、对象树 1、对象树的析构 2、自定义类的编写…

代码随想录刷题题Day37

刷题的第三十七天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C Day37 任务 ● 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费 ●总结 1 最佳买卖股票时机含冷冻期 309.最佳…

C 语言->编译和链接实现原理

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;橘橙黄又青-CSDN博客 今天学习&#xff1a;浅学编译和链接内部实现原理 前提&#xff1a;本文是在gcc编译环…

C++总结笔记

1. 简介 1、面向对象程序设计 面向对象的四大特性 1&#xff09;封装 2&#xff09;继承 3&#xff09;多态 4&#xff09;抽象 2、标准库 标准C由三个部分组成 1&#xff09;核心语言&#xff1a;提供了所有的构件块 2&#xff09;C标准库&#xff1a;提供了大量的函…

chrony介绍和安装

chrony介绍和安装 1.chrony&#xff08;时间同步服务&#xff09; 1.1 chrony介绍 Chrony 是一个用于时间同步的软件&#xff0c;它旨在提供高精度的系统时钟同步。Chrony 软件包括一个 NTP&#xff08;Network Time Protocol&#xff0c;网络时间协议&#xff09;服务器和客…

【Linux第二课-权限】操作系统、Linux用户、Linux权限、Linux文件类型、粘滞位

目录 操作系统shell外壳为什么有shell外壳shell外壳是什么shell外壳工作原理 Linux用户root用户与非root用户root用户与普通用户的切换普通用户 --> root用户root用户 --> 普通用户普通用户 --> 普通用户对一条指令提升为root权限进行执行 Linux权限Linux中的权限角色…

【Linux】Linux系统的生态

Linux中安装软件 Linux中安装软件一般有三种方式&#xff1a; 源代码安装rpm包安装yum安装 1.源代码安装 有些软件本来就是开源的&#xff0c;如果不想用别人直接发布好的软件&#xff0c;我们就可以把源代码下载下来&#xff0c;在我们的环境中编译&#xff0c;自己安装 …