IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Mybatis Plus【3】——左手乐观锁、右手逻辑删除在数据层为所欲为 -> 正文阅读

[Java知识库]Mybatis Plus【3】——左手乐观锁、右手逻辑删除在数据层为所欲为

三连多大胆,就有多大产!开源促使进步,献给每一位技术使用者和爱好者!
干货满满,摆好姿势,准备发车

一、乐观锁

乐观锁是用来解决多线程情况下同一条数据同时可能被多人一起修改,造成数据紊乱的一种解决方案,当更新一条数据时,希望这条数据没有被别人更新,也就是说实现线程安全的数据更新。

判断有没有被修改的策略就是在准备更新时获取该数据的版本,在更新时检查版本是否相同,更新后将数据的版本修改来实现。

对于乐观锁和悲观锁的详细介绍可以参考 什么是乐观锁,什么是悲观锁 文章

1.1、实现方式

在Mybatis Plus步骤如下

  • 取出记录时,获取当前version
  • 更新记录时,带上这个version
  • 执行更新时,set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

1.2、实现步骤

  • 在数据表中新增 version 字段,类型为int
  • 在实体类中新增 version 属性,并使用 @Version 注解修饰
  • 元数据处理接口添加 version 的 insert 默认值(可以不做,目的在于自动填充有个默认值而已)
  • 编写配置类,配置 乐观锁插件

1.3、数据库添加字段

基于 MyBatis-Plus【2】 也就是上篇文章的基础,在您自己的表中创建一个 version 字段,也可以按照下方sql实现:

ALTER TABLE `user` ADD COLUMN `version` INT

1.4、实体类

  • @Version:实现乐观锁注解
  • @TableField(fill = FieldFill.INSERT):实现自动填充,在新增数据时填充一个初始的版本号,当然您也可以设置数据库的默认值等方式
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;

1.5、元数据处理接口

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    // 使用MP实现添加操作,该方法执行
    @Override
    public void insertFill(MetaObject metaObject) {
        ......
        this.setFieldValByName("version",1,metaObject);
    }

    // 使用MP实现修改操作,该方法执行
    @Override
    public void updateFill(MetaObject metaObject) {
        ......
    }
}

1、支持的数据类型只有int、Integer、long、Long、Date、Timestamp、LocalDateTime
2、整数类型下 newVersion = oldVersion + 1
3、newVersion会写回到entity中
4、仅支持 updateById(id) 和 update(entity,warpper)方法
5、在update(entity,warpper)方法下,warpper不能重用

1.6、乐观锁配置类

@Configuration
@EnableTransactionManagement
@MapperScan(value = "com.buye.mp.mapper")
public class MyBatisPlusConfig {

    /**
     * 新版 插件配置方式
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }

    /**
     * 旧版
     * @Bean
     * public OptimisticLockerInterceptor optimisticLockerInterceptor() {
     *    return new OptimisticLockerInterceptor();
     * }
     */
}

1.7、测试

首先新增一条数据,因为有自动填充version,所以它的version是1,然后再根据id修改

@Test
public void addUser() {
    // 创建User对象,并设置属性,此处没有设置id
    User user = new User();
    user.setName("不夜同学");
    user.setEmail("test10.@baomidou.com");
    user.setAge(14);
    // 调用insert函数将用户添加进数据库
    int row = userMapper.insert(user);
    System.out.println("成功新增" + row + "条数据");
}

@Test
public void testOptimisticLokker() {
    // 1、根据id查询数据
    User user = userMapper.selectById(1452181379893747714L);
	// 2、设置,修改数据
    user.setAge(18);

    userMapper.updateById(user);
}

效果图如下,默认version为1,修改后version为2

请添加图片描述

sql执行如下
请添加图片描述

二、逻辑删除

逻辑删除假删除,将对应数据中代表是否删除字段状态修改为 被删除状态,之后数据仍然存在与数据库中;

物理删除真实删除:将对应数据从数据库中删除,之后查询不到此条被删除数据;

2.1、实现步骤

  • 想数据库中添加 deleted 字段

  • 实体类中添加 deleted 字段

  • 元对象处理器接口添加 deleted 的 insert 默认值(可以不做,只是为了新增数据时有默认值)

  • application.properties 加入配置

  • 在配置类中配置Bean【mybatis plus高版本已经不需要配置了】

2.2、新增字段

ALTER TABLE `user` ADD COLUMN `deleted` boolean

2.3、实体类新增deleted字段

  • @TableLogic:实现逻辑删除注解
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;

2.4、application配置文件

该配置可以不做,默认0未删除,1以删除

# 逻辑删除已删除值(默认为1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# 逻辑删除未删除值(默认为0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0

2.5、测试

2.5.1、新增数据

@Test
public void addUser() {
    // 创建User对象,并设置属性,此处没有设置id
    User user = new User();
    user.setName("不夜学长");
    user.setEmail("test11.@baomidou.com");
    user.setAge(14);
    // 调用insert函数将用户添加进数据库
    int row = userMapper.insert(user);
    System.out.println("成功新增" + row + "条数据");
}

新增数据的deleted默认值为0,这里我们并没有设置自动填充哦!
请添加图片描述

2.5.2、删除数据

@Test
public void testLogicDelete() {

    int row = userMapper.deleteById(1452267209106739202L);
    System.out.println(row);

}

测试结果

请添加图片描述

2.5.3、添加逻辑删除后的查询

配置逻辑删除下的查询自带上 deleted = 0 条件
请添加图片描述

2.6、注意

如果需要查询出被逻辑删除的数据,那么就需要自己写sql语句啦

只对自动注入的sql起效:

  • 插入: 不作限制
  • 查找: 追加where条件过滤掉已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
  • 更新: 追加where条件防止更新到已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
  • 删除: 转变为 更新

例如:

  • 删除: update user set deleted=1 where id = 1 and deleted=0
  • 查找: select id,name,deleted from user where deleted=0

字段类型支持说明:

  • 支持所有数据类型(推荐使用 Integer,Boolean,LocalDateTime)
  • 如果数据库字段使用datetime,逻辑未删除值和已删除值支持配置为字符串null,另一个值支持配置为函数来获取值如now()

附录:

  • 逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。
  • 如果你需要频繁查出来看就不应使用逻辑删除,而是以一个状态去表示

好了,对于mybatis-plus的 逻辑删除乐观锁 分享到这里,如果您的项目中使用到mybatis-plus,这两个功能一定要用上。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-26 08:43:52  更:2021-11-26 08:44:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:56:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码