mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比,于是写了个插件。 (1)

简介: mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比,于是写了个插件。 (1)

使用mybatis逆向工程的时候,delete方法的使用姿势不对,导致表被清空了,在生产上一刷新后发现表里没数据了,一股凉意从脚板心直冲天灵盖。


于是开发了一个拦截器,并写下这篇文章记录并分享。


这锅只能自己背了


你用过 mybatis 逆向工程(mybatis-generator-maven-plugin)生成相关文件吗?

就像这样式儿的:


可以看到逆向工程帮我们生成了实体类、Mapper 接口和 Mapper.xml。


用起来真的很方便,我用了好几年了,但是前段时间翻车了。


具体是怎么回事呢,我给大家摆一下。


先说一下需求吧。就是在做一次借据数据迁移的过程中,要先通过 A 服务的接口拿到所有的借据和对应的还款计划数据,然后再对这些借据进行核查,如果不满足某些添加,就需要从表中删除借据和对应的还款计划。


借据和对应的还款计划存放在两张表中,用借据号来关联。


而上线之后,我在一片欢声笑语中把还款计划表清空了,而这个必现的问题,在测试阶段同学还没有测试出来。


事情发生后我赶紧找到了 DBA 协助修复数据:


是怎么回事呢,为了模拟这个场景,我在本地创建了两张表,订单表(orderInfo)和订单扩展表(orderInfoExt),他们之间用订单号进行关联:


仅仅是做演示,所以两张表是非常简单的,


我们假设现在表里面的这条订单号为 2020060666666 的数据经过判断是错误数据,我当时写的代码体现在单元测试里面是这样的:


看出问题了吗?


第 42 行用的 example 对象还是 OrderInfo 的 example。而真正的 OrderInfoExt 对象的 exampleExt 对象没有进行任何赋值的操作。


为什么会出现这样的乌龙呢?


都怪 idea 太智能了!(强行找个借口)


我只需要打一个 ex 然后回个车.... example 就出现在代码里面了。


而这种没有参数的 example 传进去,在 mapper.xml 里面是这样处理的:


执行一下,看看效果:


看到 delete from order_info_ext 语句。你说你慌不慌?



当然在线上的服务器肯定是看不到执行的 SQL 的,但是当报警短信一条一条接着来的时候,当连上数据库一看表,发现数据没了的时候。

你说你慌不慌?


反正我一刷新后发现表里没数据了,一股凉意从脚板心直冲天灵盖。这种时候都还是要小小的心慌一下,先大喊一声“卧槽!数据怎么没了?”


然后赶紧报备,准备找 DBA 捞数据吧。


还好,本次误删不影响正常业务。


数据恢复过程就不说了,聊一下这事发生后我的一点思考吧。


哦,对了,还得说一下测试同学为什么没有发现这个问题。这个问题确实是一个必现的问题,测试案例上也写了这个测试点。


但是测试同学查看数据的时候用的是 select 语句,查询条件给的是确实需要被删除的数据 。


然后分别在两个表里面执行后发现:数据确实是没了。


是的,是数据确实是没了。整个表都干净了。


看着测试妹子惊慌失措的样子,我还能怎么说呢?


这锅,不甩了,我自己背下来吧。


重新审视逆向工程


我们先看看逆向工程帮我们生成的接口:


我相信用过 mybatis 逆向工程的朋友们,一看到这几个接口就知道了:哟,这都是老朋友了。


当我再去重新审视这些接口的时候我会发现其实还有会有一些问题的。


比如 delete 这样的高危语句我们还是需要尽量的手写 xml。


比如 updateByExample 同样存在由于误操作没有 where 条件,导致全表更新的情况。

比如 select 语句是查出了整个对象,但是有时间我们可能只需要对象里面的某个值而已。


比如 select 语句针对大表、关键表操作的时候,不能从代码的角度限定 SQL 必须带上索引字段查询。


上面的这些问题我们怎么处理呢?


我的建议是不要使用 mybatis 的逆向工程,全都手写。


开个玩笑。我们肯定不能因噎废食,何况逆向工程确实是帮我们做了很多工作,极大的方便我们这样的 CRUD Boy 进行 CRUD。


所以,我想 mybatis 的逆向工程肯定是有什么配置来控制生成哪些接口的,别问为什么,问就是直觉。


因为要是让我去开发这样的一个插件,我肯定也会提供对应的开关配置。


我现在的想法是不让它给我生成 delete 相关的接口,这个接口用起来我心里害怕。

所以怎么配置呢?


我们去它的 DTD 文件里面找一下嘛:


这个文件不长,一共也才 213 行,你能发现这一块东西:


你用脚指头想也能知道,这就是我们要找的开关配置。从 DTD 文件的描述中来看,这个几个参数是配置在 table 标签里面的。

我们去试一下:


果然是这样的。然后我们进行相关配置如下:


再生成一下:


果然,delete 相关的接口没了。


然后我们程序中真的需要 delete 操作的时候,再自己去手写 xml 文件。

那你自己写的 xml 文件也忘记写 where 条件了这么办?


这个月工资别领了。自己好好反思反思。


当然,就算你真的忘记写了,下面这个拦截器还能给你兜个底,帮你一把。


mybatis 拦截器使用


其实这个方案是我想到的第一个方案。导致上面问题的原因很简单嘛,就是执行了delete 语句却没有 where 条件。


那么我们可以拦截到这个 SQL 语句,然后对其进行两个判断:


是否是 delete 语句。 如果是,是否包含 where 条件。


那么问题来了,我们怎么去拦截到这个 SQL 呢?


答案就是我们可以开发一个 mybatis 插件呀,就像分页插件那样。


插件,听起来很高端的样子,其实他就是个拦截器。实现起来非常简单。


先去官网上看一下:


中文:https://mybatis.org/mybatis-3/zh/configuration.html#plugins

英文:https://mybatis.org/mybatis-3/configuration.html


在官网上,对于插件这一模块的描述是这样的:


通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可。


正如官网说的这样,插件开发、使用起来是非常简单的。只需要三步:


1.实现 Interceptor 接口。


2.指定想要拦截的方法签名。


3.配置这个插件。

目录
相关文章
|
5月前
|
SQL XML Java
8、Mybatis-Plus 分页插件、自定义分页
这篇文章介绍了Mybatis-Plus的分页功能,包括如何配置分页插件、使用Mybatis-Plus提供的Page对象进行分页查询,以及如何在XML中自定义分页SQL。文章通过具体的代码示例和测试结果,展示了分页插件的使用和自定义分页的方法。
8、Mybatis-Plus 分页插件、自定义分页
|
2月前
|
SQL Java 数据库连接
深入 MyBatis-Plus 插件:解锁高级数据库功能
Mybatis-Plus 提供了丰富的插件机制,这些插件可以帮助开发者更方便地扩展 Mybatis 的功能,提升开发效率、优化性能和实现一些常用的功能。
388 26
深入 MyBatis-Plus 插件:解锁高级数据库功能
|
2月前
|
SQL Java 数据库连接
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。本文讲解了最新版MP的使用教程,包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段等核心功能。
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
|
2月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
2月前
|
Java 数据库连接 数据库
spring和Mybatis的逆向工程
通过本文的介绍,我们了解了如何使用Spring和MyBatis进行逆向工程,包括环境配置、MyBatis Generator配置、Spring和MyBatis整合以及业务逻辑的编写。逆向工程极大地提高了开发效率,减少了重复劳动,保证了代码的一致性和可维护性。希望这篇文章能帮助你在项目中高效地使用Spring和MyBatis。
53 1
|
3月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
175 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
4月前
|
SQL Java 数据库连接
解决mybatis-plus 拦截器不生效--分页插件不生效
本文介绍了在使用 Mybatis-Plus 进行分页查询时遇到的问题及解决方法。依赖包包括 `mybatis-plus-boot-starter`、`mybatis-plus-extension` 等,并给出了正确的分页配置和代码示例。当分页功能失效时,需将 Mybatis-Plus 版本改为 3.5.5 并正确配置拦截器。
1348 6
解决mybatis-plus 拦截器不生效--分页插件不生效
|
4月前
|
SQL XML Java
springboot整合mybatis-plus及mybatis-plus分页插件的使用
这篇文章介绍了如何在Spring Boot项目中整合MyBatis-Plus及其分页插件,包括依赖引入、配置文件编写、SQL表创建、Mapper层、Service层、Controller层的创建,以及分页插件的使用和数据展示HTML页面的编写。
springboot整合mybatis-plus及mybatis-plus分页插件的使用
|
3月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
111 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
3月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
762 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个