MybatisPlus(5)

前言🍭

❤️❤️❤️SSM专栏更新中,各位大佬觉得写得不错,支持一下,感谢了!❤️❤️❤️

Spring + Spring MVC + MyBatis_冷兮雪的博客-CSDN博客

上篇讲了增删的操作,这篇讲修改操作中的一个问题以及它对应的解决方案——乐观锁,还有代码生成器的实现。

一、乐观锁(update)🍭

业务并发现象带来的问题: 秒杀。

我们应该都遇过买东西限量秒杀吧,这个时候这么多人一起抢,我们应该怎么去实现秒杀程序呢?

下面我们会讲解2000访问量的秒杀实现,如果是更多人的话就应该使用其他更好的方法了。

1、添加字段和实体类属性🍉

添加version字段,默认值为1

 实体类属性也添加应该version属性:

package com.example.domain;import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;@Data
/*@TableName("tbl_user")*/
public class User {@TableId(type= IdType.ASSIGN_ID)private Long id;private String name;@TableField(value = "pwd",select = false)private String password;private Integer age;private String tel;/*@TableLogic(value = "0",delval = "1")*/private Integer deleted;@Versionprivate Integer version;@TableField(exist = false)private Integer online;
}

 2、@Version原理🍉

当人人去进行秒杀时,成功抢到商品的用户,会更新用户的version值,

update set_abc=1,version = version + 1 where version=1

如上面这个SQL一样。当一个仅剩的一个商品被抢走,这个version值就会变化,其他人就会显示抢不到商品。

添加乐观锁拦截器(和分页功能一样)🍓

使用这个和分页功能一样,需要添加拦截器:

package com.example.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.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MpConfig {@Beanpublic MybatisPlusInterceptor mpInterceptor(){//1.定义Mp拦截器MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();//2.添加具体的拦截器mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());//3、添加乐观锁拦截器mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mpInterceptor;}
}

3、测试代码🍓

我们去修改用户id=2的用户名:

 @Testvoid testUpdate(){User user=new User();user.setId(2L);user.setName("编程");userDao.updateById(user);}

运行发现,version值并没有发生改变:

 这是因为我们没有去添加version值,便无法改变version值。

@Testvoid testUpdate(){User user=new User();user.setId(2L);user.setVersion(1);user.setName("编程");userDao.updateById(user);}

 添加用户的version发现,进行修改操作之后version值+1了:

但是这样手动添加version值很麻烦,我们可以先查询用户信息,然后去进行修改,也是可以的:

@Testvoid testUpdate(){//1.先通过要修改的数据id将当前数据查询出来User user = userDao.selectById(2L);//2.将要修改的属性逐一设置进去user.setName("编程1号");userDao.updateById(user);}

 可以看到version经过用户修改又加了1。

 4、秒杀测试🍓

我们前后修改两次用户名,看最终结果如何:

@Testvoid testUpdate(){//1.先通过要修改的数据id将当前数据查询出来User user = userDao.selectById(2L);     //version=3User user2 = userDao.selectById(2L);    //version=3user2.setName("编程 aaa");userDao.updateById(user2);              //version=>4user.setName("编程 bbb");userDao.updateById(user);               //verion=3?条件还成立吗?}

 可以看到只修改了一次,用户名修改为了 编程 aaa而后面的修改操作未进行:

这和我们上面说的情况是一样的,用户信息进行了修改,version值也会加一,因为你一开始查询到的version值为3,这个时候version已经变成了4,就无法进行修改成为 编程 bbb 了。

二、代码生成器🍭

1、模板🍉

既然是代码生成器,那肯定是有模板的,那我们来看看UserDao,观察看看,哪些是模板里的,哪些是需要更改的。

package com.example.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.domain.User;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserDao extends BaseMapper<User> {
}

看下面,对于不同的Dao类只需要将下面红框框里的东西替换就行,其他的就是模板。换句话说我们只要将下面红框框里面的东西替换,又是一个新的Dao类。

不仅仅是Dao类实体类也可以提取出模板。

2、代码生成器🍉

模板:MyBatisPlus提供

数据库相关配置:读取数据库获取信息

开发者自定义配置:手工配置

Ⅰ、配置🍓

我们新建一个SpringBoot项目:

pom.xml:其中有所需要的代码生成器velocity模板引擎以及其他需要的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.14</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>mybatis-plus</artifactId><version>0.0.1-SNAPSHOT</version><name>mybatis-plus</name><description>mybatis-plus</description><properties><java.version>1.8</java.version></properties><dependencies><!-- spring webmvc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mybatisplus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><!-- druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency><!-- mysql --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- 代码生成器 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version></dependency><!-- velocity模板引擎 --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

Generator类:添加数据库配置

package com.example;import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;public class Generator {public static void main(String[] args) {AutoGenerator autoGenerator=new AutoGenerator();DataSourceConfig dataSource=new DataSourceConfig();dataSource.setDriverName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/ku2022?characterEncoding=utf8");dataSource.setUsername("root");dataSource.setPassword("123456");autoGenerator.setDataSource(dataSource);autoGenerator.execute();}
}

运行之后会给我打开一个文件夹:

 可以发现多了一个com文件夹,我们打开里面的controller文件夹,可以发现它给这个库里面每一个表都生成了一个.java文件,这个就是给我们生成的代码:

但是这个东西生成的是不正确的,所以我们将这个文件夹删除掉。

Ⅱ、正确生成代码 🍓

我们应该添加其他配置,让他生成在正确的位置:

package com.example;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;public class CodeGenerator {public static void main(String[] args) {//1.获取代码生成器的对象AutoGenerator autoGenerator = new AutoGenerator();//设置数据库相关配置DataSourceConfig dataSource = new DataSourceConfig();dataSource.setDriverName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/ku2022?serverTimezone=UTC");dataSource.setUsername("root");dataSource.setPassword("123456");autoGenerator.setDataSource(dataSource);//设置全局配置GlobalConfig globalConfig = new GlobalConfig();//输出的位置globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");    //设置代码生成位置globalConfig.setOpen(false);    //设置生成完毕后是否打开生成代码所在的目录globalConfig.setAuthor("热爱编程的林兮");    //设置作者globalConfig.setFileOverride(true);     //设置是否覆盖原始生成的文件globalConfig.setMapperName("%sDao");    //设置数据层接口名,%s为占位符,指代模块名称globalConfig.setIdType(IdType.ASSIGN_ID);   //设置Id生成策略autoGenerator.setGlobalConfig(globalConfig);//2.执行生成操作autoGenerator.execute();}
}

我们看到上面,点开GlobalConfig源码:

 默认生成代码在D盘。

Ⅲ、生成的代码1🍓

我们运行代码:

可以看到在Java目录下的con文件夹生成了一个baomidou文件夹。

我们打开entity实体类:

可以看到作者就是上面配置文件中设置的作者:热爱编程的林兮 

我们在生成的代码进行修改,然后重新运行 代码生成器。

我们运行发现,它又变回去了,这是因为代码进行了覆盖 

 是下面这段代码带来的影响:

globalConfig.setFileOverride(true);     //设置是否覆盖原始生成的文件

重新运行代码,就会将代码全部重新覆盖。

Ⅳ、生成的代码2🍓

我们继续在CodeGenerator添加新配置:

//设置包名相关配置PackageConfig packageInfo = new PackageConfig();packageInfo.setParent("com.aaa");   //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径packageInfo.setEntity("domain");    //设置实体类包名packageInfo.setMapper("dao");   //设置数据层包名autoGenerator.setPackageInfo(packageInfo);

我们把之前的代码(baomidou)删除掉,重新运行代码。

可以发现重新生成了一个名字为aaa文件夹,不再是原来的名字了。还有实体类的包名也修改了,变成了domin,数据层包名也变成了dao。

Ⅴ、生成的代码3 🍓

//策略设置StrategyConfig strategyConfig = new StrategyConfig();strategyConfig.setInclude("tbl_user");  //设置当前参与生成的表名,参数为可变参数strategyConfig.setTablePrefix("tbl_");  //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名  例如: User = tbl_user - tbl_strategyConfig.setRestControllerStyle(true);    //设置是否启用Rest风格strategyConfig.setVersionFieldName("version");  //设置乐观锁字段名strategyConfig.setLogicDeleteFieldName("deleted");  //设置逻辑删除字段名strategyConfig.setEntityLombokModel(true);  //设置是否启用lombokautoGenerator.setStrategy(strategyConfig);

之前库里面有五个表,这次通过上面代码我只生成了tbl_user表的代码(只想生成我指定表的代码),而且表的实体类加了@Data注解(启用了lombok),设置了乐观锁字段名还有逻辑删除字段名,以及删除了数据表的tbl_前缀。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DataX实现Mysql与ElasticSearch(ES)数据同步

文章目录 一、Linux环境要求二、准备工作2.1 Linux安装jdk2.2 linux安装python2.3 下载DataX&#xff1a; 三、DataX压缩包导入&#xff0c;解压缩四、编写同步Job五、执行Job六、定时更新6.1 创建定时任务6.2 提交定时任务6.3 查看定时任务 七、增量更新思路 一、Linux环境要求…

加密算法发展简介

1&#xff1a;对称加密算法 客户端加密数据和服务端解密数据&#xff0c;使用的相同的秘钥&#xff1a; 固定秘钥&#xff1a;双方约定好一个固定秘钥&#xff1b; 随机秘钥&#xff1a;双方约定每次建立连接的时候&#xff0c;某固定BYTE为秘钥&#xff1b; 缺点&#xff1a…

JK405R-SOP16录音芯片ic方案的功能简介,可以内置录音30秒-高采样率

一、简介 JK405R是一颗SOP16封装的录音芯片&#xff0c;专用于录音的应用&#xff0c;芯片内置了30秒的录音空间&#xff0c;同时还支持外扩 spiflash方便不同录音时长的应用需求。芯片内置MIC的放大器&#xff0c;并且增益可调 同时芯片还具备超低功耗&#xff0c;待机2uA。…

2023/9/17周报

摘要 本周阅读了两篇论文&#xff0c;其一为一种基于空气质量时频域特征提取的hybrid预测方法&#xff0c;另一篇为基于烛台与视觉几何群模型的 PM2.5 变化趋势特征提取与分类预测方法。在第一篇文章中&#xff0c;通过小波变化&#xff0c;对数据进行分频&#xff0c;并设计了…

Linux界的老古董

Slackware 是由 Patrick Volkerding 制作的 Linux 发行版&#xff0c;从 1993 年发布至今也一直在 Patrick 带领下进行维护。7 月 17 日&#xff0c;Slackware 才刚刚过完它 24 岁的生日&#xff0c;看似年纪轻轻的它&#xff0c;已然是 Linux 最古老的发行版。 Slackware 的发…

[vue问题]开发中问题集合

“TypeError: Cannot read property ‘Request’ of undefined” 这是测试文件的报错&#xff0c;最后发现是因为项目启动的时候就报错了&#xff0c;是其它错误导致的&#xff0c;所以测试文件才会提示这种错误&#xff0c;当启动报错修复后&#xff0c;该问题没有了 热加载…

[计组03]进程详解2

目录 应用程序 系统调用 驱动 软件 再看进程 进程管理 如何管理 ? 创建一个进程 注意 PCB 文件描述表 进程相关重点 为什么有进程调度 虚拟空间地址 这次我们从更加详细全面的角度看一下进程在计算机中体系中的展现 应用程序 应用程序 调动 系…

VR古迹复原——数字化复原圆明园,开创文化遗产保护新方式

圆明园是中国历史上一处重要的文化遗产&#xff0c;曾经被誉为“万园之园”&#xff0c;但在1860年的英法联军侵华战争中被毁。近年来&#xff0c;虚拟现实技术不断发展&#xff0c;广州华锐互动利用VR全景技术复原了圆明园&#xff0c;通过VR设备&#xff0c;人们可以在家中就…

CRM与chatGPT结合的效果

2023年ChatGPT是当之无愧的行业热词&#xff0c;从诞生到爆红短短5天&#xff0c;注册用户数就超过100万&#xff0c;截止到2023年1月底已经有超过1亿用户。在这样的背景下&#xff0c;Zoho CRM系统在业内较早推出集成ChatGPT的相关功能&#xff0c;接下来我们就来分享CRM接入C…

MySQL实现单个字段根据特定字符拆分

1.字段内容 2.想得到的效果 步骤1中&#xff0c;每一条记录的FJ字段&#xff0c;根据分号&#xff0c;拆分成多条&#xff0c;如下图所示&#xff1a; 3.具体实现 说明&#xff1a; SELECT DISTINCTsubstring_index(substring_index(a.要拆分的字段, 分隔字符, b.help_top…

【视觉检测】电源线圈上的导线弯直与否视觉检测系统软硬件方案

 检测内容 线圈上的导线弯直与否检测系统。  检测要求 检测线圈上的导线有无弯曲&#xff0c;弯曲度由客户自己设定。检测速度5K/8H625PCS/H。  视觉可行性分析 对样品进行了光学实验&#xff0c;并进行图像处理&#xff0c;原则上可以使用机器视觉进行测试测量…

基于springboot+vue的企业面试预约管理系统

基于springbootvue的企业面试预约管理系统 预约面试管理系统&#xff0c;可以通过学生&#xff0c;企业角色进行登录 登录后可以查看发布的岗位&#xff0c;发布人&#xff0c;发布时间&#xff0c;面试时间&#xff0c;招聘时间&#xff0c;招聘单位简介等 查看用户管理信息

第十三章总结

一.泛型 1.定义泛型类 泛型机制语法&#xff1a; 类名<T> 其中&#xff0c;T是泛型的名称&#xff0c;代表某一种类型。 【例13.6】创建带泛型的图书类 代码&#xff1a; 结果&#xff1a; 2.泛型的常规用法 (1)定义泛型类时声明多个变量 class MyCla…

9.14 C++作业

仿照vector手动实现自己的myVector&#xff0c;最主要实现二倍扩容功能 #include <iostream>using namespace std;template <typename T> class Myvector {T *data; //存储数据的数组int len; //当前数组的长度int mycapa; //容纳数据的总容量public://…

[春秋云境] CVE-2022-32991

CVE-2022-32991 靶标介绍 该CMS的welcome.php中存在SQL注入攻击。 解题过程 进入主界面&#xff0c;没有明显可以注入的地方&#xff0c;先注册登录。 登录之后的界面 此处有个?q1但是多次测试后&#xff0c;感觉不是注入点。 点击这个按钮&#xff0c;进入新的界面。 多…

完全保密的以太坊交易:Aztec网络的隐私架构

1. 引言 Aztec为隐私优先的以太坊zkRollup&#xff1a;即其为具有完全隐私保护的L2。 为了理解私有交易的范式变化性质&#xff0c;以及为什么将隐私直接构建到网络架构中很重要&#xff0c;必须首先讨论为什么以太坊不是私有的。 2. 以太坊&#xff1a;公有链 以太坊为具有…

elasticsearch1

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…

翻牌闯关游戏

翻牌闯关游戏 3关&#xff1a;关卡由少至多12格、20格、30格图案&#xff1a;12个玩法&#xff1a;点击两张卡牌&#xff0c;图案一到即可消除掉 记忆时长(毫秒)&#xff1a;memoryDurationTime:5000 可配置&#xff0c;默认5000 提示游戏玩法&#xff1a;showTipsFlag:1 可…

【Redis7】--3.Redis持久化

Redis持久化 Redis持久化(Redis persistence)是指将数据写入持久化存储&#xff0c;如固态硬盘(SSD) Redis提供了一系列持久化选项&#xff0c;这些包括&#xff1a; RDB(redis数据库)&#xff1a;RDB持久化方式能够在指定的时间间隔对数据进行快照存储AOF(追加文件)&#x…

MongoDB-1入门介绍

NoSQL NoSQL(NoSQL Not Only SQL)&#xff0c;意即反SQL运动&#xff0c;指的是非关系型的数据库 优点 1、对数据库高并发读写。 2、对海量数据的高效率存储和访问。 3、对数据库的高可扩展性和高可用性。 弱点&#xff1a; 1、数据库事务一致性需求 2、数据库的写实时性…