【MyBatis-Plus】进阶之乐观锁、悲观锁逻辑删除分页和查询构造器的使用

目录

一、乐观锁、悲观锁

1、什么是乐观锁和悲观锁

①乐观锁(Optimistic Locking):

②悲观锁(Pessimistic Locking):

③实现方式

2、乐观锁和悲观锁的区别

①乐观锁(Optimistic Locking)

②悲观锁(Pessimistic Locking)

③总结

3、案例

①如何实现乐观锁?

②如何使用MyBatis-Plus实现乐观锁?

二、逻辑删除

1、什么是逻辑删除

2、为什么使用逻辑删除

3、案例

①官方说明

②配置方式

③演示

三、分页和查询构造器

1、查询构造器

2、分页(PaginationInnerInterceptor)


一、乐观锁、悲观锁

1、什么是乐观锁和悲观锁

①乐观锁(Optimistic Locking):

  1. 乐观锁假设多个事务在大多数情况下不会相互冲突,因此在数据读取时不会立即加锁。
  2. 数据需要更新时,会检查在此期间是否有其他事务对该数据进行过修改。如果,则当前事务会失败并回滚
  3. 乐观锁通常通过版本号或时间戳来实现,其中读取数据时获取版本号或时间戳,更新数据时检查版本号或时间戳是否发生变化。

②悲观锁(Pessimistic Locking):

  1. 悲观锁则相反,它假设多个事务在大多数情况下会相互冲突,因此在数据读取时就直接加锁
  2. 这意味着其他事务在加锁释放之前无法访问该数据
  3. 悲观锁可以通过数据库的行级锁、表级锁等方式实现。

③实现方式

  • 乐观锁: MyBatis Plus 支持使用 Version 注解实现乐观锁。在实体类中,可以添加一个版本字段并使用 Version 注解来标记为乐观锁字段。在更新操作时,MyBatis Plus 会自动检查版本号是否发生变化,以决定是否允许更新。
  • 悲观锁: MyBatis Plus 提供了 Lock 注解支持悲观锁。当需要在更新操作时对记录加锁时,可以使用 Lock 注解标记对应的 SQL 语句。这会在执行该 SQL 语句时自动加锁,以确保数据的一致性。

2、乐观锁和悲观锁的区别

①乐观锁(Optimistic Locking)

  1. 操作数据时持乐观态度,认为数据在并发操作期间不太可能被其他事务修改,因此不会立即加锁
  2. 更新数据时,会检查在此期间是否有人修改了数据。如果检测到数据已被修改,则放弃更新操作否则,执行更新
  3. 乐观锁适用于读操作频繁、写操作较少的场景,因为不加锁的特性在性能方面可能优于悲观锁

②悲观锁(Pessimistic Locking)

  1. 在操作数据时持悲观态度,认为数据在并发操作期间很可能被其他事务修改。
  2. 因此,在读取数据时就直接对数据进行加锁,防止其他事务同时修改,直到当前事务完成操作并释放锁。
  3. 悲观锁适用于写操作频繁的场景,可以避免因数据被其他事务修改而导致的冲突。

③总结

  1. 加锁时间不同:乐观锁在读取数据时不会对其加锁,而是在写入时进行比较和加锁操作;悲观锁在读取数据时就会对其加锁。

  2. 冲突处理方式不同:乐观锁会在写入时进行比较和冲突检测,如果版本号不一致则操作失败,需要重新读取数据;悲观锁则会阻塞其他进程对该数据的访问,直到当前进程完成操作并解锁。

  3. 适用场景不同:乐观锁适用于并发量比较小、数据量比较大、操作更多为读取的场景;悲观锁适用于并发量比较大、数据量比较小、操作更多为写入的场景。

3、案例

①如何实现乐观锁?

@Version注解标记乐观锁,通过 version 字段来保证数据的安全性,当修改数据的时候,会以 version 作为条件,当条件成立的时候才会修改成功。

1)取出记录时,获取当前 version

2)更新时,带上这个 version

3)执行更新时,`update tableName set version = oldVersion + 1 where version = oldVersion`

4)如果 version 不对,就更新失败

②如何使用MyBatis-Plus实现乐观锁?

  1. 给数据库表添加 version 字段,并设置默认值为1
  2. 实体类增加 version 属性,并添加 @Version 注解
        /*** 乐观锁*/@Versionprivate Integer version;
  3. 配置乐观锁插件
    @Configuration
    public class MybatisPlusConfig {/*** 添加分页插件* 乐观锁插件*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    //        乐观锁插件interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
    }

     
  4. 测试
        @Testvoid contextLoads() {//先查询,再修改Book book = bookMapper.selectById("1685091066406");book.setBookname("Java编程思想");book.setPrice(100f);bookMapper.updateById(book);}
    从控制台的日志信息发现:修改数据时 version 作为条件判断,并且 version 自动完成自增操作,即:version = version+1

    测试多线程下乐观锁失败:
    @Test
    public void demo2(){//线程1:Book book1 = bookMapper.selectById("1685091066406");book1.setBookname(".Net之入门");book1.setPrice(110f);//线程2:(在线程1的修改操作未来得及执行时介入)Book book2 = bookMapper.selectById("1685091066406");book2.setBookname("Python之入门");book2.setPrice(200f);bookMapper.updateById(book2);//如果没有乐观锁就会覆盖插队线程的值!bookMapper.updateById(book1);//更新失败
    }

总结:就是一次

二、逻辑删除

1、什么是逻辑删除

        逻辑删除是指文件没有被真正的删除,只不过是文件名的第一个字节被改成操作系统无法识别的字符。这种删除操作通常是可逆的,也就是说,用适当的工具或软件可以把删除的文件恢复出来。逻辑删除和物理删除是两种不同的文件删除方式。在计算机中,资料数据等都以文件形式存储。当文件需要被删除时,可以根据实际需求选择逻辑删除或物理删除

2、为什么使用逻辑删除

原因、作用:

  1. 数据恢复:逻辑删除只是修改了文件名或其他元数据,并没有真正删除数据。因此,被删除的数据仍然存在于存储介质中,可以被恢复。这种设计方便数据恢复,保护了数据本身的价值。
  2. 保护数据完整性:逻辑删除操作不会对数据本身造成损害,从而保护了数据的完整性。
  3. 操作简单:逻辑删除操作相对简单,只需修改元数据即可,而无需清空存储介质或进行其他复杂操作。
  4. 灵活性高:逻辑删除允许在将来某个时间点恢复被删除的数据,因此具有很高的灵活性。
  5. 减少存储空间占用:物理删除需要清空存储介质,可能会浪费大量的存储空间。相比之下,逻辑删除不会占用额外存储空间。
  6. 满足法规和政策要求:在某些行业或应用场景中,法规和政策可能要求保留被删除的数据,以便进行审计或追溯。逻辑删除可以满足这些要求,而不会造成数据丢失。

3、案例

①官方说明

只对自动注入的 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()

附录:

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

②配置方式

全局配置

例: application.yml

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

在对应的实体类中添加逻辑删除字段,如下:

    //逻辑删除@TableField("statu")private Integer statu;

局部配置

请在实体类对应的逻辑删除属性上加入@TableLogic注解。其中@TableLogic注解属性介绍如下:

属性名类型说明
valueString未逻辑删除的值
delvalString已逻辑删除的值

在实体类上配置逻辑删除字段,如下:

/**
* 逻辑删除,1=删除,0=正常
*/
@TableLogic(value = "0",delval = "1")
@TableField("statu")
private Integer statu;

③演示

创建junit测试,使用deleteById方法进行测试。

    @Testvoid contextLoads() {//先使用deleteById删除对应的数据bookMapper.deleteById("493783504224325");//使用查询方法查询数据//List<Book> books = bookMapper.selectList(null);//books.forEach(System.out::println);}

观察idea控制台输出结果,会发现执行deleteById方法后,不再显示delete语句,而是update语句。则表示逻辑删除成功,可查看MySQL数据表中的结果。

然后,执行selectList(null)方法,可发现查询语句的where条件后加入逻辑删除字段deleted=0的判断处理,表示只查询出未逻辑删除的数据。

三、分页和查询构造器

1、查询构造器

QueryWrapper是Mybatis-Plus提供的一个条件构造器,用于快速构建SQL查询语句的条件部分。通过使用QueryWrapper,我们可以方便地进行单表数据的查询、修改、删除等操作。

QueryWrapper的语法类似于Mybatis的XML文件中的where标签,其最终会被转换为SQL语句的条件部分。我们可以通过链式调用的方式,不断添加查询条件,从而构建出复杂的查询条件。

2、分页(PaginationInnerInterceptor)

支持的数据库

  • mysql,oracle,db2,h2,hsql,sqlite,postgresql,sqlserver,Phoenix,Gauss ,clickhouse,Sybase,OceanBase,Firebird,cubrid,goldilocks,csiidb,informix,TDengine,redshift

  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库,优炫数据库,星瑞格数据库

配置分页插件

@Configuration
public class MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//注册分页插件mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return mybatisPlusInterceptor;}
}

实现分页

int page=1;
int row=10;
//条件构造器
QueryWrapper<Book> wrapper=new QueryWrapper<>();
//设置条件
//TODO
//设置分页
Page<Book> result = bookMapper.selectPage(new Page<Book>().setCurrent(page).setSize(row), wrapper);
List<Book> records = result.getRecords();
System.out.println("总记录数:"+result.getTotal());
records.forEach(System.out::println);

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE】多线程(6) -- 定时器的使用及实现

目录 定时器是什么 标准库中的定时器的使用 实现定时器 定时器是什么 Java中的定时器是一种机制&#xff0c;用于在预定时间执行某个任务。它允许开发人员在指定的时间间隔内重复执行任务&#xff0c;或在指定的延迟之后执行任务。定时器是Java提供的一种方便的工具&#xf…

图分割算法之贪心算法

1 贪心算法的思想 Linear Deterministic Greedy partitioning (LDG)考虑在分割的时候将邻居结点放置在一起&#xff0c;以减少切割边。它采用贪心算法将一个结点放置在包含其邻居最多的子图中&#xff0c;同时保证每个子图的结点负载均衡&#xff0c;整个算法流程图如下其中 C …

单文件超过4GB就无法拷贝到U盘?这个你一定要知道

前言 随着现在科技发展&#xff0c;小伙伴们所使用的数据也越变越大。还记得WindowsXP流行的时候&#xff0c;XP的镜像文件仅为几百MB大小。 但是现在随便一个系统就有可能超过4GB。 如果单个文件超过4GB就有可能没办法拷贝进U盘&#xff0c;在这里就需要给小伙伴们普及一下U…

用ChatGPT挑选钻石!著名珠宝商推出-珠宝GPT

根据Salesforce最新发布的第五版《互联网购物报告》显示&#xff0c;ChatGPT等生成式AI的出现、快速发展&#xff0c;对零售行业和购物者产生了较大影响。可有效简化业务流程实现降本增效&#xff0c;并改善购物体验。 著名珠宝商James Allen为了积极拥抱生成式AI全面提升销售…

vue2使用svg图片

1、安装依赖包&#xff1a; npm install svg-sprite-loader --save-dev 2、新建assets/icons/svg中放置svg图片和index.js文件 svgo.yml文件 index.js import Vue from vue import SvgIcon from /components/SvgIcon// svg component// register globally Vue.component(sv…

antd中DatePicker禁选范围如何设置

1、解决日期禁选问题 在官方api中也提到&#xff0c;可以设置disabledDate来实现日期的禁选 语法&#xff1a; js中定义disabledData函数 const disabledDate (current) > { 设置禁选范围 } 在DatePicker 标签中引入 同时我们要知道antd是默认使用moment.js来实现日期格式…

【ES】es介绍

倒排索引&#xff08;Inverted Index&#xff09;和正排索引&#xff08;Forward Index&#xff09; 正排索引是一种以文档为单位的索引结构&#xff0c;它将文档中的每个单词或词组与其所在的文档进行映射关系的建立。正排索引通常用于快速检索指定文档的内容&#xff0c;可以…

Python列表数据处理全攻略(三):常用内置方法轻松掌握

文章目录 引言Python列表常用内置方法count()功能介绍语法示例注意事项 index()功能介绍语法示例注意事项&#xff1a; insert()功能介绍语法示例注意事项总结 结束语 引言 亲爱的读者&#xff0c;你好&#xff01;Python的列表在数据结构中占据着核心地位&#xff0c;对于学习…

k8s-cni网络 10

Flannel vxlan模式跨主机通信原理 在同一个节点上的pod 流量通过cni网桥可以直接进行转发&#xff1b; 在需要跨主机访问时&#xff0c;数据包通过flannel(隧道) 知道另一边的mac地址&#xff0c;就可以拿到另一边的ip地址&#xff0c;然后构建常规的以太网数据包&#xff0c;…

github登录需要双因素认证(Two-factor authentication)

前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 github登录需要双因素认证&#xff08;Two-factor authentication&#xff09; 今天登录github发现需要绑定双因素才能够登录 我们…

具有权威性的工信部证书怎么考

工信部证书的考试流程如下&#xff1a; 选择正规报考机构&#xff1a;选择一家权威的培训机构或考试中心&#xff0c;确保其具有相应的资质和经验。 提交个人报考资料&#xff1a;根据考试机构的要求&#xff0c;提交相关的个人报考资料&#xff0c;如身份证、学历证明、工作…

【单片机项目实战】温度控制系统

本项目的主要作用是实现温度调控&#xff0c;通过设定一个预定的温度值&#xff0c;实现实时检测外界温度&#xff0c;当外界温度小于预定值时&#xff0c;电机正转&#xff0c;实现降温效果&#xff1b;当外界温度大于预定值时&#xff0c;电机反转&#xff0c;实现升温效果&a…

SpringBoot多线程与任务调度总结

一、前言 多线程与任务调度是java开发中必须掌握的技能&#xff0c;在springBoot的开发中&#xff0c;多线程和任务调度变得越来越简单。实现方式可以通过实现ApplicationRunner接口&#xff0c;重新run的方法实现多线程。任务调度则可以使用Scheduled注解 二、使用示例 Slf…

TiDB SQL调优案例TiFlash

背景 早上收到某系统的告警tidb节点挂掉无法访问&#xff0c;情况十万火急。登录中控机查了一下display信息&#xff0c;4个TiDB、Prometheus、Grafana全挂了&#xff0c;某台机器hang死无法连接&#xff0c;经过快速重启后集群恢复&#xff0c;经排查后是昨天上线的某个SQL导…

2022年全球软件质量效能大会(QECon北京站2022)-核心PPT资料下载

一、峰会简介 当前&#xff0c;新一轮科技革命和产业变革正在重塑全球经济格局&#xff0c;以云计算为代表的新一代信息技术创新活跃&#xff0c;与实体经济深度融合&#xff0c;推动泛在连接、数据驱动、智能引领的数字经济新形式孕育而生。 新兴技术的出现给测试乃至整个软…

小米路由器2(R2D) 安装 MIXBOX

1. 先刷开发版 ROM http://www1.miwifi.com/miwifi_download.html 进入上述网页&#xff0c;找到 R2D 点击下载 开发版 ROM 教程 看 下载按钮上边的 “刷机教程” 刷机教程 2. 开启SSH工具 登录自己的小米账号后&#xff0c;里面会显示出 自己的 root密码&#xff1b; 默认…

记一次修复外网无法访问vmware里面的虚拟机的网络端口的问题

发现一个奇怪的网络问题&#xff0c;vmware里一个程序的端口通过vmnat穿透出来&#xff0c;然后这个端口就能够通过局域网被其他机器访问&#xff0c;但是另一个网段就没法访问这个端口。使用主机上的其他程序使用开启同样的端口&#xff0c;另一个网段的机器却可以访问。我想不…

Android Security PIN 相关代码

开发项目遇到一个问题&#xff0c;具体描述及复制步骤如下&#xff1a; 就是开启"Enhanced PIN privacy"(增强的PIN隐私)的时候输入秘密的时候还是会显示数字 如下图&#xff0c;应该是直接是“.” 不应该出现PIN 密码 想要的效果如下图&#xff1a; 设置的步骤如下图…

中职网络安全Server2002——Web隐藏信息获取

B-2&#xff1a;Web隐藏信息获取 任务环境说明&#xff1a; 服务器场景名&#xff1a;Server2002&#xff08;关闭链接&#xff09;服务器场景用户名&#xff1a;未知 有问题需要环境加q 通过本地PC中渗透测试平台Kali使用Nmap扫描目标靶机HTTP服务子目录&#xff0c;将扫描子…

用户规模破亿!基于文心一言的创新应用已超4000个

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…