当前位置: 首页 > article >正文

【MyBatis-Plus】逻辑删除、乐观锁、防全表更新和删除实现 MyBatisX插件 高级扩展

文章目录

  • 一、逻辑删除实现
  • 二、乐观锁实现
    • 2.1 悲观锁和乐观锁场景和介绍
    • 2.2 具体技术和方案:
    • 2.3 版本号乐观锁技术的实现流程
    • 2.4 使用mybatis-plus数据使用乐观锁
  • 三、防全表更新和删除实现
  • 三、代码生成器(MyBatisX插件)


一、逻辑删除实现

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

逻辑删除实现:

  • 数据库 和 实体类 添加逻辑删除字段
    • 数据表添加逻辑删除字段
    • 可以是一个布尔类型、整数类型或枚举类型。
ALTER TABLE USER ADD deleted INT DEFAULT 0 ;  # int 类型 1 逻辑删除 0 未逻辑删除
  • 实体类添加逻辑删除属性
@Data
public class User {
    private Long id;
    @TableField(value = "nickname",exist = false)
    private String name;
    private Integer age;
    private String email;

    // 当前属性对应的列就是逻辑删除的状态字段
    // 当删除数据时,自动变成修改此列的属性值 默认0未删除 1删除
    // 查询时,默认只查询 deleted = 0 未删除的数据
    @TableLogic
    private Integer deleted;
}
  • 指定逻辑删除字段和属性值
    • 单一指定
      • 在实体类属性上创建属性 指定注解@TableLogic
    • 全局指定
      • yml 配置文件 添加 logic-delete-field
        1
        源码中默认值 就设置了未删除0 删除为1,可以保持默认即可。
        1
  • 测试:
    • 逻辑删除:不使用delete语句而是修改语句 update user set deleted=1 where id=#{id}
    • 物理删除:delete from user where id=#{id}
    @Test
    public void delete_test2(){
        userMapper.deleteById(2);
    }

Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0
1
正常查询 : 默认查询非逻辑删除数据

二、乐观锁实现

2.1 悲观锁和乐观锁场景和介绍

需求前置:并发问题演示
1
使用乐观锁/悲观锁解决:
乐观锁悲观锁是在并发编程中用于处理并发访问资源竞争的两种不同的机制

  • 悲观锁
    • 当A在使用时,上锁了,B尝试使用被拒绝,因为上锁了
    • 只能等A用完后,解锁了,B再次去尝试使用。
  • 乐观锁
    • 当A使用,不会上锁,B可以尝试使用,但被告知已被占用,不能用
    • 区别于悲观锁 -> 乐观锁的B会反复的尝试,直到A使用完毕
  • 这两者都是解决并发数据问题思路,不是具体技术

2.2 具体技术和方案:

乐观锁:

  • 版本号/时间戳
    • 为数据添加一个版本号或时间戳字段,每次更新数据时
    • 比较当前版本号或时间戳与期望值是否一致
    • 若一致则更新成功,否则表示数据已被修改,需要进行冲突处理。
  • CAS(Compare-and-Swap)
  • 无锁数据结构
    • 无锁队列、无锁哈希表等…

悲观锁:

  • 锁机制
    • 互斥锁(Mutex Lock)或读写锁(Read-Write Lock)
  • 数据库锁
    • 数据库层面使用行级锁或表级锁来控制并发访问
  • 信号量

2.3 版本号乐观锁技术的实现流程

  • 每条数据添加一个版本号字段version
  • 取出记录时,获取当前 version
  • 更新时,检查获取版本号是不是数据库当前最新版本号
  • 如果是[证明没有人修改数据], 执行更新, set 数据更新 , version = version+ 1
  • 如果 version 不对[证明有人已经修改了],我们现在的其他记录就是失效数据!就更新失败

2.4 使用mybatis-plus数据使用乐观锁

  • 添加版本号更新插件,在springboorMain类
    1
    /**
     * 将 mybatis-plus 插件加入到IOC容器
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        //mybatis-plus的插件集合【将需要的插件加入到这个集合中即可,比如分页插件,乐观锁插件等】
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //乐观锁【版本号插件】mybatis-plus 会在更新时,每次帮助我们对比版本号字段和增加版本号+1
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
  • 数据库添加version字段
ALTER TABLE USER ADD VERSION INT DEFAULT 1 ;  # int 类型 乐观锁字段

1

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 仅支持 updateById(id)update(entity, wrapper) 方法
  • 实体类添加version属性
    @Version
    private Integer 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);
    }

先查再改:
1
1

三、防全表更新和删除实现

针对 update 和 delete 语句 作用: 阻止恶意的全表更新删除
在这里插入图片描述

  • 添加防止全表更新和删除拦截器
        // 防止全表删除和更新拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());

1
### Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of table update operation

三、代码生成器(MyBatisX插件)

1
1

使用mybatisX插件,自动生成sql语句实现

MyBatisX快速代码生成_官方文档


http://www.kler.cn/news/272946.html

相关文章:

  • VMD + CEEMDAN 二次分解,CNN-Transformer预测模型
  • Cookie与Session
  • 水电站防水淹厂房视频、报警系统解决方案
  • mac安装rust环境
  • 实现C++自定义的String类
  • 47.全排列II
  • Java微服务分布式事务框架seata
  • 【Mysql事务】
  • 用python如何实现智能合约?如何使用remix编写solidity智能合约并部署上链
  • 【how2j练习题】HTML部分综合练习
  • (二十五)Flask之MTVMVC架构模式Demo【重点:原生session使用及易错点!】
  • 消息队列面试题
  • 2024西工大数据结构理论上机作业(头歌 C)持续更新中~
  • 寻找可能认识的人
  • 安卓面试网络知识基础 1-5
  • ​LeetCode解法汇总303. 区域和检索 - 数组不可变
  • 【已解决】MySQL:常用的除法运算+精度处理+除数为0处理
  • 强化PaaS平台应用安全:关键策略与措施
  • C++ 11:基于范围的 for 循环
  • java的23种设计模式03-创建型模式02-抽象工厂方法