【MyBatis Plus】004 -- MyBatis Plus高级(AR、MP插件、自定义全局操作、自动填充、逻辑删除、枚举、代码生成器)

news2024/12/28 5:21:11

目录

1、ActiveRecord

1.1 开启AR之旅(根据主键 id 进行查询)

1.2 新增数据

1.3 更新操作

1.4 删除操作

1.5 根据条件查询

2、Oracle 主键 Sequence

2.1 部署Oracle环境

2.2 创建表以及序列

2.3 jdbc驱动包

2.4 修改application.properties

2.5 配置序列

2.6 测试

3、MyBatis-Plus的插件

3.1 mybatis的插件机制

3.2 执行分析插件

3.3 性能分析插件

3.4 乐观锁插件

3.4.1 主要适用场景

3.4.2 插件配置

3.4.3 注解实体字段

3.4.4 测试

3.4.5 特别说明

4、SQL注入器实现自定义全局变量

4.1 编写MyBaseMapper

4.2 编写MySqlInjector

4.3 编写FindAll

4.4 注册到Spring容器(自定义的SQL注入器 MySqlInjector)

4.5 测试

5、自动填充功能

5.1 添加@TableField注解

5.2 编写MyMetaObjectHandler

5.3 测试

6、逻辑删除(标记隐藏展示)

6.1 修改表结构

6.2 配置

6.3 测试

7、通用枚举

7.1 修改表结构

7.2 定义枚举

7.3 配置

7.4 修改实体

7.5 测试

8、代码生成器

8.1 创建工程

8.2 代码

8.3 测试

9、MyBatisX 快速开发插件


1、ActiveRecord

ActiveRecord(简称AR)一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于ActiveRecord 往往只能感叹其优雅,所以我们也在 AR 道路上进行了一定的探索,喜欢大家能够喜欢

1.1 开启AR之旅(根据主键 id 进行查询)

在MP中,开启AR非常简单,只需要将实体对象继承Model即可

Model中实现了各种各样的方法:

因此我们可以直接通过User对象来调用CURD方法

测试用例:(根据主键 id 进行查询)

但虽然我们在测试用例中没有显式的使用Mapper方法,但在ModelCURD的底层实现中依然是需要使用我们之前创建的继承了BaseMapperUserMapper来进行操作,所以Mapper接口是不能省略的,一定要切记!

测试结果

1.2 新增数据

测试用例:

测试结果:

数据库表结果:

1.3 更新操作

测试用例:

结果:

1.4 删除操作

测试用例:

结果:

1.5 根据条件查询

测试用例:

结果:

2、Oracle 主键 Sequence

mysql中,主键往往是自增长的,这样使用起来是比较方便的,如果使用的是Oracle数据库,那么就不能使用自增长了,就得使用Sequence 序列生成id值了

2.1 部署Oracle环境

为了简化环境部署,这里使用Docker环境进行部署安装Oracle

# 拉取镜像

docker pull sath89/oracle-12c

# 创建容器

docker create --name oracle -p 1521:1521 sath89/oracle-12c

# 启动

docker start oracle && docker logs -f oracle

# 部分启动过程省略

……

PL/SQL procedure successfully completed.

Starting import from '/docker-entrypoint-initdb.d':

ls: cannot access /docker-entrypoint-initdb.d/*: No such file or directory

Import finished

Database ready to use. Enjoy! ;)

# 通过用户名密码即可登录

用户名和密码为: system/oracle

下面使用navicat12进行连接并操作oracle:

需要注意的是:由于安装的Oracle是64位版本,所以navicat也是需要使用64为版本,否则连接不成功。

2.2 创建表以及序列

建表语句:

--创建表,表名以及字段名都要大写

CREATE TABLE "TB_USER" (

"ID" NUMBER(20) VISIBLE NOT NULL ,

"USER_NAME" VARCHAR2(255 BYTE) VISIBLE ,

"PASSWORD" VARCHAR2(255 BYTE) VISIBLE ,

"NAME" VARCHAR2(255 BYTE) VISIBLE ,

"AGE" NUMBER(10) VISIBLE ,

"EMAIL" VARCHAR2(255 BYTE) VISIBLE

)

--创建序列

CREATE SEQUENCE SEQ_USER START WITH 1 INCREMENT BY 1

2.3 jdbc驱动包

由于版权原因,我们不能直接通过maven的中央仓库下载oracle数据库的jdbc驱动包,所以我们需要将驱动包安装到本地仓库:

安装成功:

安装完成后的坐标:(测试是否可以成功导入)

导入成功:

2.4 修改application.properties

对于application.properties的修改,需要修改2个位置,分别是:

2.5 配置序列

使用Oracle的序列需要做2件事情:

Ⅰ、需要配置MP的序列生成器到Spring容器:

Ⅱ、在实体对象(pojo)中指定序列的名称:(这里clazzlong是因为id的类型也为long)

2.6 测试

测试用例:

结果:

3、MyBatis-Plus的插件

3.1 mybatis的插件机制

MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

1. Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)

2. ParameterHandler (getParameterObject, setParameters)

3. ResultSetHandler (handleResultSets, handleOutputParameters)

4. StatementHandler (prepare, parameterize, batch, update, query)

我们看到了可以拦截Executor接口的部分方法,比如update,query,commit,rollback等方法,还有其他接口的一些方法等

总体概括为:

1. 拦截执行器的方法

2. 拦截参数的处理

3. 拦截结果集的处理

4. 拦截Sql语法构建的处理

拦截器示例:(测试运行,会先进入对象代理plugin方法(此时它获取的target是一个MybatisSimpleExecutor对象),只会才会被intercept方法拦截,拦截到update方法之后,我们可以通过proceed()方法对其放行,然后再次进入plugin方法(此时它获取的target是一个MybatisDefaultParameterHandler对象),在这个过程中plugin方法一共会被执行四次,因为MyBatis 允许使用插件来拦截的方法就包括四种,所以每种都会在plugin方法中进行一次包装)

注入到Spring容器:

或者通过xml配置,mybatis-config.xml

3.2 执行分析插件

在MP中提供了对SQL执行的分析的插件,可用作阻断全表更新、删除的操作,注意:该插件仅适用于开发环境,不适用于生产环境

SpringBoot配置:(SQL分析插件)

测试:(测试全表的更新,SQL分析器的阻断效果)

结果:(可以看到,当执行全表更新时,会抛出异常,这样有效防止了一些误操作)

这是一个禁止的操作

如果是非全表的更新,那么会怎么样呢?

测试方法:

可以正常执行:

3.3 性能分析插件

性能分析拦截器,用于输出每条 SQL 语句及其执行时间,可以设置最大执行时间,超过时间会抛出异常

注意:该插件只用于开发环境,不建议生产环境使用

配置:(Mybatis-config.xml),其也可以在MybatisPlusConfig中进行配置

执行结果:(可以看到,执行时间为11ms。如果将maxTime设置为1,那么,该操作会抛出异常)

超时,抛出异常:

3.4 乐观锁插件

3.4.1 主要适用场景

意图:

当要更新一条记录的时候,希望这条记录没有被别人更新

乐观锁实现方式:

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

3.4.2 插件配置

spring xml:

spring boot:

3.4.3 注解实体字段

需要为实体字段添加@Version注解

Ⅰ、为表添加version字段,并且设置初始值为1:

Ⅱ、为User实体对象(pojo)添加version字段,并且添加@Version注解(表示它是一个乐观锁):

3.4.4 测试

测试用例:(测试乐观锁)

执行日志:

可以看到,更新的条件中有version条件,并且更新的version为2。

如果再次执行,更新则不成功。这样就避免了多人同时更新时导致数据的不一致

3.4.5 特别说明

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity 中
  • 仅支持 updateById(id) 与 update(entity, wrapper) 方法
  • 在 update(entity, wrapper) 方法下, wrapper 不能复用!!!

4、SQL注入器实现自定义全局变量

我们已经知道,在MP中,通过AbstractSqlInjectorBaseMapper中的方法注入到了Mybatis容器,这样这些方法才可以正常执行

那么,如果我们需要扩充BaseMapper中的方法,又该如何实现呢?

下面我们以扩展findAll方法(自定义方法)为例进行学习

4.1 编写MyBaseMapper

其他的Mapper都可以继承该Mapper,这样实现了统一的扩展

如:

4.2 编写MySqlInjector

如果直接继承AbstractSqlInjector的话,原有的BaseMapper中的方法将失效,所以我们选择继承DefaultSqlInjector进行扩展

4.3 编写FindAll

4.4 注册到Spring容器(自定义的SQL注入器 MySqlInjector)

4.5 测试

输出的SQL:

至此,我们实现了全局扩展SQL注入器

5、自动填充功能

有些时候我们可能会有这样的需求,插入或者更新数据时,希望有些字段可以自动填充数据,比如密码、version 等。在MP中提供了这样的功能,可以实现自动填充

5.1 添加@TableField注解

为password添加自动填充功能,在新增数据时有效。

FieldFill提供了多种模式选择:

5.2 编写MyMetaObjectHandler

插入数据时填充:

// 先获取到password的值,再进行判断,如果为空,就进行填充,如果不为空,就不做处理

更新数据时填充:

5.3 测试

结果:(默认在插入时填充密码为123456

6、逻辑删除(标记隐藏展示)

开发系统时,有时候在实现功能时,删除操作需要实现逻辑删除,所谓逻辑删除就是将数据标记为删除,而并非真正的物理删除(非DELETE操作),查询时需要携带状态条件,确保被标记的数据不被查询到。这样做的目的就是避免数据被真正的删除

MP就提供了这样的功能,方便我们使用,接下来我们一起学习下:

6.1 修改表结构

tb_user表增加deleted字段,用于表示数据是否被删除,1代表删除,0代表未删除:

同时,也修改User实体,增加deleted属性并且添加@TableLogic注解:

6.2 配置

application.properties:

6.3 测试

执行的SQL:

数据库表:

测试查询:

执行的SQL:

已经查询不出来了,可见,已经实现了逻辑删除。

7、通用枚举

解决了繁琐的配置,让 mybatis 优雅的使用枚举属性

7.1 修改表结构

7.2 定义枚举

7.3 配置

7.4 修改实体

7.5 测试

测试插入数据:

SQL:

数据库表:

查询:(这里的插件可以将枚举和1,2进行转化)

结果:

从测试可以看出,可以很方便的使用枚举了

查询条件时也是有效的:

SQL:

8、代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率

8.1 创建工程

创建工程:

导入pom.xml:

8.2 代码

直接复制模板即可:(以下仅展示部分代码内容)

8.3 测试

代码已生成:

实体对象:

9、MyBatisX 快速开发插件

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx 搜索并安装

功能:

  • Java 与 XML 调回跳转
  • Mapper 方法自动生成 XML

测试用例:

结果:

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

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

相关文章

LC-1041 困于环中的机器人(模拟,快慢指针找环)

1041. 困于环中的机器人 难度中等148 在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方。注意: 北方向 是y轴的正方向。南方向 是y轴的负方向。东方向 是x轴的正方向。西方向 是x轴的负方向。 机器人可以接受下列三条指令之一: "…

第一讲 初识Python

Python简介 Python(英式发音:/ˈpaɪθən/;美式发音:/ˈpaɪθɑːn/)是由荷兰人吉多范罗苏姆(Guido von Rossum)发明的一种编程语言,是目前世界上最受欢迎和拥有最多用户群体的编…

【Colab】Colab使用教程(跑本地文件)

文章目录前言一、上传本地文件二、Colaboratory使用1、连接2、调整文件3、运行文件三、未来可期前言 首先,自己想办法注册谷歌账号,本文不讲。 Colaboratory网址:https://colab.research.google.com/ 谷歌云端硬盘:https://dri…

【软件测试二】开发模型和测试模型,BUG概念篇

目录 1.软件的生命周期 2.瀑布模型 3.螺旋模型 4.增量,迭代 5.敏捷---scrum 1. 敏捷宣言 2.角色 6. 软件测试v模型 7.软件测试w模型 8.软件测试的生命周期 9.如何描述一个BUG 10.如何定义BUG的级别 11.BUG的生命周期 12.产生争执怎么办 1.软件的生命周期…

26岁转行网络安全,成功上岸安全开发!

前言 我是去年 9 月 22 日才正式学习网络安全的,之前在国营单位工作了 4 年,在长沙一个月工资只有 5000 块,而且看不到任何晋升的希望,如果想要往上走,那背后就一定要有关系才行。 而且国营单位的气氛是你干的多了&a…

【Fluent UDF】浮点溢出错误后初始化对UDF运行的影响、停止正在进行的计算后重载UDF再计算会产生的效果

一、初始化对UDF运行的影响 初始化只会初始化网格上的物理数据、在UDF中常用的实际时间flow-time(CURRENT_TIME)、迭代步数N_ITER、UDM中的数据(其实也就是网格物理数据)。 初始化之后,UDF程序中的静态变量不会再初始…

【牛客刷题专栏】0x22:JZ21 调整数组顺序使奇数位于偶数前面(一)(C语言编程题)

前言 个人推荐在牛客网刷题(点击可以跳转),它登陆后会保存刷题记录进度,重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏:个人CSDN牛客刷题专栏。 题目来自:牛客/题库 / 在线编程 / 剑指offer: 目录 前言问…

Java阶段二Day03

Java阶段二Day03 文章目录 Java阶段二Day03V5BirdBootApplicationClientHandlerHttpServletRequest V6BirdBootApplicationClientHandlerHttpServletRequest V7BirdBootApplicationClientHandlerHttpServletRequestHttpServletResponse V8BirdBootApplicationClientHandlerHttp…

【Unity入门】14.值类型和引用类型

【Unity入门】值类型和引用类型 大家好,我是Lampard~~ 欢迎来到Unity入门系列博客,所学知识来自B站阿发老师~感谢 (一)值类型 (1)C#的值类型 1. 布尔类型(bool) 2. 字符类型&#x…

【软考备战·希赛网每日一练】2023年4月18日

文章目录 一、今日成绩二、错题总结第一题第二题第三题 三、知识查缺 题目及解析来源:2023年04月18日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析: MTTF:平均无故障时间 MTTR:平均故障修复时间 可用性/可靠性MTTF…

一文入门Typrscript和Vue3

一、TypeScript快速上手 在TypeScript专栏已经详细介绍过TypeScript,在此总结一下TypeScript和Vue3的基础知识。 1. 初识 TypeScript 1.1 TypeScript 的介绍 TypeScript是一种由微软开发的开源、跨平台的编程语言。它是JavaScript的超集,最终会被编译为JavaScrip…

Python轻量级Web框架Flask(9)——图书馆项目

1、项目要求: 创建一个项目,用来说明出版社,书籍和作者的关系。作者和书籍之间的关系:1对多(一本书由一个作者完成,一本书可以有多个创作者)出版社和书籍之间的关系:多对多&#xf…

day15 消息队列

目录 消息队列 消息队列的使用 发送消息 消息的接收 消息队列的控制 消息队列 概念: 消息队列是system V IPC对象的一种; 消息队列有消息队列ID来唯一标识; 消息队列就是一个消息的列表。用户可以在消息队列中添加消息、读取消息等&a…

有介质的高斯定理详细证明(电偶极子模型)以及例题讲解

目录 静电场中的电介质 电极化强度的引入 电偶极子模型的计算 电介质极化过程 极化电荷引入 推导 各向同性和线性的电介质 例题 静电场中的电介质 电介质与导体的区别:所有的粒子被束缚在原子核周围(限制空间) 电介质分为两种 1.无…

OldWang带你了解MySQL(十)

文章目录 🔥MySQL事务🔥使用事务🔥事务的并发问题🔥MySQL的用户管理🔥MySQL分页查询 🔥MySQL事务 事务简介 事务是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完…

【网络小知识】当我在浏览器url输入文本后的解析流程/http协议对比https协议

当我们在地址栏输入信息之后,我们会得到浏览器给我们一个返回的信息,那么这个信息怎么出来的?且看下文~~~ 目录 ⭐一、浏览器url解析流程⭐二、http协议对比https协议 ⭐一、浏览器url解析流程 在浏览器地址栏输入文本后,比如 “…

window.postMessage()接收不到信息(失效)

问题描述 按照正常的代码逻辑,应该是这个样子,通过iframe打开子窗口,能够正常通信。 // 接收端(父窗口) window.onmessage function (e) {// 逻辑代码 }// 发送端(子窗口) window.parent.po…

第一次参加CSDN周赛,这体验很难说···

👨‍💻个人主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 本文章收录于专栏 【CSDN周赛】 本篇文章目录🌏前言🌏一、勾股数🌸题目描述🌸题解&…

Android Activity 了解

前言 : Android 系统的四大组件分别是 1 活动 (Activity) 2 服务(Service) 3 广播接收器(Broadcast Receiver) 4 内容提供器 (Content Provider) 其中活动是所有安卓应用程序的…

rust闭包(Closure)

闭包(Closure) 闭包在现代化的编程语言中普遍存在。闭包是一种匿名函数,它可以赋值给变量也可以作为参数传递给其它函数,不同于函数的是,它允许捕获调用者作用域中的值。Rust 闭包在形式上借鉴了 Smalltalk 和 Ruby 语言,与函数最…