mybatis-plus02--Lesson2

news/2025/3/10 18:03:24/文章来源:https://www.cnblogs.com/5ran2yl/p/18756786

CRUD和myBatis-plus插件

1.Insert方法和雪花算法

当一个数据表中的id为主键时,且插入的数据的时候不插入主键id,那么会发生什么呢?接下来就进行一次简单测试,还是那个User表,插入其它属性,不插入主键id。

测试方法:

  @Testpublic void testInsert(){User user = new User();user.setAge(18);user.setName("maming");user.setEmail("maming@qq.com");int insert = userDao.insert(user);System.out.println(insert);}

 

通过上面的方式进行插入之后数据库表中的数据会改变为:

 我们可以轻易发现id值变成了一串数字,和上面的id格格不入,这就是自动生成的全局唯一id,使用的就是雪花算法

雪花算法(Snowflake Algorithm)是Twitter开源的一种分布式唯一ID生成算法,用于在分布式系统中生成全局唯一的ID。其主要特点包括:

  1. 全局唯一性:通过特定的算法设计,确保生成的ID在分布式系统中的全局唯一性。

  2. 时间有序性:生成的ID中包含时间戳信息,使得ID按照时间顺序递增,便于排序和查询。

  • 符号位(1位):最高位固定为0,表示ID为正数。

  • 时间戳(41位):记录ID生成的时间,精确到毫秒级。41位时间戳可以表示大约69年的时间范围(从某个自定义的起始时间开始计算),确保ID在较长时间内不会重复。

  • 数据中心ID(5位):用于标识不同的数据中心,通常在5到10位之间,根据实际需求配置。这有助于在多数据中心环境中区分不同数据中心生成的ID。

  • 机器ID(5位):用于标识同一数据中心内的不同机器或进程,通常在5到10位之间。与数据中心ID结合,确保每台机器生成的ID唯一。

  • 序列号(12位):在同一毫秒内,通过序列号区分不同的ID。12位序列号可以支持每毫秒生成4096个唯一的ID,满足高并发场景下的需求。

除此之外,insert方法插入id还有其它的生成方式,都可以使用@ValueId注解来指定: @TableId(type = IdType.ASSIGN_ID) //默认的雪花算法生成

 2.update方法

使用update方法有很多,常用的就是使用ID进行更改和使用条件选择器

使用ID更改:

@Testpublic void testUpdate(){User msf = new User().setAge(16).setName("msf").setId(1L);int i = userDao.updateById(msf);System.out.printf("---", i);}

使用一个对象进行更改,只要传入id属性值,那么就会将其作为条件,并且mybaits-plus的方法都是默认 动态sql,没多一个属性就会多拼接更改列,根本不需要自己来设置,非常高效

 使用条件选择器进行更改:

@Testpublic void testUpdate(){User msf = new User().setAge(100);QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("name", "msf"); //where name =‘msf’int i = userDao.update(msf, wrapper);System.out.println(i);}

 3.自动填充

 MyBatis-Plus 提供了一个便捷的自动填充功能,用于在插入或更新数据时自动填充某些字段,如创建时间、更新时间等

为了测试,我们需要在数据库更新两个字段,用户后期自动填充:

ALTER TABLE userADD COLUMN create_time DATE AFTER email;
ALTER TABLE userADD COLUMN update_time DATE AFTER create_time;

 

实时更新后面的实体类:

    @TableField(fill = FieldFill.INSERT)private Date createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime;

 

@TableField注解,可以配置在进行数据库操作的时候自动填入那些属性,INSERT即插入的时候需要使用,而INSERT_UPDATE是插入和删除都需要自动填充

实现 MetaObjectHandler:创建一个类来实现 MetaObjectHandler 接口,并重写 insertFill 和 updateFill 方法

// java example
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("开始插入填充...");this.setFieldValByName("createTime", new Date(), metaObject);this.setFieldValByName("updateTime", new Date(), metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {log.info("开始更新填充...");this.setFieldValByName("updateTime",new Date(), metaObject);}
}

 

测试插入新数据后是否自动填入时间:

@Testpublic void testAutoFill(){User user = new User().setAge(100).setEmail("maming@qq.com").setName("ok");int i = userDao.insert(user);}

 

数据库插入截图:

 测试更新:

@Testpublic void testAutoFill2(){User user = new User().setAge(100).setEmail("maming@qq.com").setName("ok").setId(1898304906765160449L);userDao.updateById(user);}

 4.乐观锁插件

乐观锁是一种并发控制机制,用于确保在更新记录时,该记录未被其他事务修改。MyBatis-Plus 提供了 OptimisticLockerInnerInterceptor 插件,使得在应用中实现乐观锁变得简单。

悲观锁(Pessimistic Locking)
定义:悲观锁假设冲突会发生,并因此在整个事务期间对数据进行锁定。这意味着当一个事务正在操作某个数据项时,其他事务不能对该数据项进行任何操作,直到当前事务完成并释放锁

乐观锁(Optimistic Locking)
定义:乐观锁假设冲突不会发生,在没有锁的情况下允许所有的事务读取和尝试更新数据。只有在提交更改时才会检查是否有冲突(即是否有其他事务在此期间修改了相同的数据)。如果检测到冲突,则当前事务需要重试或回滚。

使用乐观锁相当于不给数据库上锁,而是当多个线程进行操作时,会出现更新失败的情况,这不是锁的作用,而是操作表有个version字段,当version匹配时才可以操作成功

使用前先需要配置Mybatis config,当然这也是官方写好的配置类,适用于配置mybatis-plus:

@Configuration
@MapperScan("org.cqust.testmybatisplus.dao")
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
}

 

由于这个配置文件专门用于配置mybatis-plus,故而需要扫描mapper文件的操作可以配置在这里

更新数据库表,新增一个version字段:

ALTER TABLE userADD COLUMN version int default 1 AFTER email;

 

同步实体类中的属性:

@Versionprivate Integer version;

 

新增此字段时,更新操作就会默认对比version,如果匹配跟新成功,反之更新失败

测试方法:

 @Testpublic void testVersion(){//先查询,获得version号,然后进行更改User user = userDao.selectById(2L);//填写修改信息user.setName("testVersion");user.setAge(18);//修改操作执行
        userDao.updateById(user);}

 

测试结果:

 如上图:更新语句会自动检测version是不是和查询出来的version版本对应,我们手写的更新条件并没有写上version字段,而是@version注解自动配置的

5.分页查询插件

分页插件和乐观锁插件都是mybatis-plus的插件,故而它们都需要配置在config配置类之下:

注册分页插件的代码直接从官网上复制就好了

@Configuration
@MapperScan("org.cqust.testmybatisplus.dao")
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
}

 

使用mybatis-plus插件的时候需要结合一个selectPage方法才可以使用,这就是专门用于分页的方法,查询出来的结果就是分页结果

由于mybatis-plus3.5.9就把分页插件分割出来了,故而使用的话需要单独导入其插件依赖:

  <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-jsqlparser --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-jsqlparser</artifactId><version>3.5.10.1</version></dependency>

 

测试方法:

@Testpublic void testLimit(){//拿取第1页,此页两列数据List<User> users = userDao.selectList(new Page<>(1, 2), null);users.forEach(System.out::println);}

 

查询结果:

 6.逻辑删除

 逻辑删除是一种优雅的数据管理策略,它通过在数据库中标记记录为“已删除”而非物理删除,来保留数据的历史痕迹,同时确保查询结果的整洁性。MyBatis-Plus 提供了便捷的逻辑删除支持,使得这一策略的实施变得简单高效。

它通过在数据库配置一个字段专门用于记录可见与不可见,在后面的操作增删改查都会监视这个字段,当为逻辑删除后的字段时,就不会执行操作,目的是为了保存数据

物理删除:已经从数据库中删除;逻辑删除:对增删改查进行隐藏,数据库依旧存在此数据

依旧需要先在数据库中创建一个字段:

ALTER TABLE userADD COLUMN deleted int default 1 AFTER create_time;

 

在实体类中更新属性:

   @TableLogic //逻辑删除注解private Integer deleted;

 

配置springBoot的配置属性,标志全局统一逻辑删除符号:

#逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=0
mybatis-plus.global-config.db-config.logic-not-delete-value=1

 

测试方法:

@Testpublic void testDelete(){//删除1号userDao.deleteById(1L);//删除后查询User user = userDao.selectById(1L);System.out.println(user);}

 

结果:

 如上deleted字段被改为1,查询结果:

 同时我们可以发现配置逻辑删除之后,其实走的是update方法,同时在查询的时候会需要携带上deleted = 1,即有效数据的标识符,才可以查出,故而逻辑删除后,在查询记录其实是查询不出来的,但是数据库表中又是还存在的

 

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

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

相关文章

免费好用的云服务器提供商

最近倒腾云服务器,想在阿里云上购买,结果发现价格太高,是在买不起。我只好在百度上翻呀翻,终于找到一个免费的,实名一下就能用。链接我贴这儿了,要用请自取:免费好用的云服务器提供商

2020-PTA总决赛-L3-1 那就别担心了(记忆化搜索)

dfs,记忆化搜索思路:读懂题到28分花了十分钟左右,做的时候就感觉可能要超时,因为结点稍微有点多 但是还是继续硬着头皮写下去了,果不其然,最后一个测试点超时,那么就要开dp数组了 题目大意就是找到A到B有几条路径,且是否走哪条路都能通向B28分Code: #include<bits/st…

集合论3 公理化—从罗素悖论到集合的公理化定义

集合论3 公理化—从罗素悖论到集合的公理化定义 罗素悖论 若把所有集合分为两类:第一类中的集合以其自身为元素,第二类中的集合不以自身为元素。 设第一类集合所组成的集合为\(P\),第二类所组成的集合为\(Q\)。于是有: \(P=\{A |A \in A\}\), \(Q=\{A |A \notin A\}\)。 试…

集合论2序数——从自然数系统到无穷集合的排序

集合论2序数——从自然数系统到无穷集合的排序 我们上一节,回答了下面几个关键问题 1 一个无穷集合有多少个元素?——自然数集:\(\aleph_0\),实数集:\(C=2^{\aleph_0}\) 2 不同的无穷集合里的元素“数量”是否有差异?——可数集(自然数集),不可数集(实数集—连续统)…

软件工程-作业2:第一次个人编程作业:论文查重

项目 内容这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023这个作业在哪里 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023/homework/13324这个作业的目标 学会如何个人系统化地完成软件开发,学会使用性能测试…

换到Edge?我有几点不满意。

前言 向来我都是用百分浏览器这个套壳Chrome,然而在迁移的时候由于网络的原因,存在各种不方便,于是我试着去用Edge,虽然之前也在用,但从来没作为主力使用过。 不足之处 收藏功能一塌糊涂 当我右键某个书签文件夹时,选择添加该网页,他居然要我重新选书签所在的文件夹。更…

【端口转发】 lcx工具

lcx是一个居于socket套接字实现的端口转发工具,有windows和linux两个版本,windows叫lcx.exe,linux叫portmap 一个正常的socket隧道必须具备两端:服务器端和客户端 windows下: 1、转发端口: lcx.exe -slave 公网IP 端口 内网IP 端口2、监听端口: lcx.exe -listen 转发端口…

Manus验证码生成器

Manus验证码生成器 Manus 是Monica团队推出的全球首款通用型AI助手,能将想法转化为行动:不止于思考,更注重成果。 一、关注公众号二、从底部菜单中进入三、使用Manus验证码生成器本文来自博客园,作者:方倍工作室,转载请注明原文链接:https://www.cnblogs.com/txw1958/p/…

洛谷 P1111 修复公路(并查集)

并查集这题如果想到是并查集就很简单了,按t来排序一下就好了AcCode: #include<bits/stdc++.h> using namespace std; struct way{int v1, v2, t; }; bool Cmp(const way &a, const way &b){return a.t < b.t; }vector<way> w; int unionList[1010];int…

实验1 C语言输入输出和简单程序应用编程

任务1: 源代码:1 #include <stdio.h>2 #include <stdlib.h>3 4 int main()5 {6 printf(" o \n");7 printf("<H>\n");8 printf("I I\n");9 printf(" o \n"); 10 printf("<H>\n&quo…

某考核wp

就这样抱着胸中的苦痛,前往没有你的未来My Blog robots.txt进level1.php <?php error_reporting(0); highlight_file(__FILE__); $text = $_GET["text"]; $file = $_GET["file"]; if(isset($text)&&(!preg_match("/php/",$text))…

L1G3-浦语提示词工程实践

L1G3-浦语提示词工程实践 1. 提示工程 1.1 什么是提示词 根据大模型的应用领域,可以把提示词分为五类。其中,“文本生成”提示词是最基础最重要的。 提示词是调用生成式AI能力的基础接口。提示词调用生成式AI能力的两个阶段如下:大模型词元预测的原理:获取输入文本,模型处…