聊聊 Mybatis 动态 SQL

iBatis的动态SQL语句 iBatis最全的动态SQL语句,你需要的都有,资源在于大家共享 立即下载

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

e6a39086f8a927b90c146fa2c0ed620c.gif

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:勇哥java实战分享


b9ef53b3acd44c02f875ccb76c17baed.png

这篇文章,我们聊聊 Mybatis 动态 SQL  ,以及我对于编程技巧的几点思考 ,希望对大家有所启发。

9c300a0170fab372af8b507375f53d17.png

1 什么是 Mybatis 动态SQL

如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。

Mybatis  借助功能强大 OGNL 表达式,可以根据参数条件,动态生成执行 SQL 。

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。

b107470169b1f738123c685ad03729c9.png

这条语句提供了可选的查询博客文章列表 ,如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 博客都会返回。

如果传入了 “title” 参数,那么就会对 “title” 一列进行模糊查找并返回对应的 BLOG 结果。

如果希望通过 “title” 和 “author” 两个参数都可以搜索,只需要加入另一个条件即可,见下图:

d6cef57f1cab42e8ba495d2421f14766.png

我们也可以使用 where 标签,该标签只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 标签也会将它们去除。

98731ecf598c8655a919116d56042f5a.png

Mybatis 还支持 choose (when, otherwise)、trim (where, set)、foreach 等其他的动态标签,这里就不一一赘述了。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

2 人生第一次线上OOM事故

我曾服务一家电商公司的用户中心,用户中心提供用户注册,查询,修改等基础功能 。

那个时候 Dubbo 等 RPC 框架并没有开源,所有的服务都以 HTTP 接口形式提供,数据传输格式是 XML 。

因为写接口非常费劲,所以为了接口复用 ,我写了一个通用接口 getUserByConditions ,该接口支持通过 「用户名」、「昵称」、「手机号」、「用户编号」这三个查询用户基本信息。

使用的是 ibatis (mybatis 的前身), SQLMap 见下图 。

b1d184253b92f3469a17727ea45f9b5a.png

当构建动态 SQL 查询时,条件通常会追加到 WHERE 子句后,而以 WHERE 1 = 1 开头,可以轻松地使用 AND 追加其他条件。

用户中心在上线后,竟然每隔三四个小时就发生了内存溢出问题 ,经过通过和 DBA 沟通,发现高频次出现全表查用户表 ,执行 SQL 变成 :

2dd94b45448d9767ee986ea6e1a281dd.png

查看日志后,发现前端传递的参数出现了空字符串 ,笔者在代码中并没有做参数校验 ,所以才出现全表查询 ,当时用户表的数据是 1000多万 ,页面调用几次,用户中心服务就 OOM 了。

最终解决问题的方式很简单,后端在接收参数时,做了参数校验。

事故虽然解决了,但对我的影响一直延续至今。我仍然记得当时站在运维同学旁边,不断的看他调整 JVM 参数 ,重启服务的画面,自己那个时候真的是羞愧难当,心中发誓:以后绝对不可以发生类似的事故 。

对于动态 SQL ,我的编程思维也经历了如下三个阶段 :

  • 前后端参数校验

  • 复用和专用要做平衡

  • 防御性编程意识

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

3 前后端参数校验

为了提升开发效率,我们人为的将系统分为前端、后端,分别由两拨不同的人员开发 ,经常出现系统问题时,两拨人都非常不服气,相互指责。

要想系统健壮,前后端应该同时做接口参数校验 (后端必须做参数校验 ),当大家都遵循这个规约时,出现系统问题的风险大大减少。

1、前端校验

c49e82ede0d06ed006d4e31e017253b6.png

前端校验,主要是为了提高用户体验,例如用户输入一个邮箱地址,要校验这个邮箱地址是否合法,没有必要发送到服务端进行校验,直接在前端用 js 进行校验即可。

但是大家需要明白的是,前端校验无法代替后端校验,前端校验可以有效的提高用户体验,但是无法确保数据完整性,因为在 B/S 架构中,用户可以方便的拿到请求地址,然后直接发送请求,传递非法参数。

2、后端校验

后端必须做参数校验,后端必须做参数校验,后端必须做参数校验 ,重要的事情表达三次。

数据在网络传输过程中有可能被篡改了,或者数据不满足业务需求,假如不做后端参数校验,则有可能导致系统异常,或者业务出现重大事故。

比如在 SpringBoot 项目中,我们可以使用 hibernate-validator 进行参数校验 。

POST、PUT 请求一般会使用 requestBody 传递参数,这种情况下,后端使用 DTO 对象进行接收。

只要给 DTO 对象加上 @Validated 注解就能实现自动参数校验。比如,有一个保存 User 的接口,要求 userName 长度是 2-10,account 和 password 字段长度

是 6-20。

在 DTO 字段上声明约束注解:

aaf1e3528c6b087f317129558b967a88.png

在方法参数上声明校验注解:

b24e09dad9972baaa7a90ae80c0f31d2.png

虽然,我们可以使用接口校验,可以保证动态 SQL 的参数正确,但是假如我们仅仅只是复用 SQLMap (Dao 方法)时,也有可能因为调用方传递参数错误,导致非预期的问题。

当然,我们也可以使用 Mybatis 拦截器 从根本上来解决,但是我想这样会加大系统的复杂度。于是,我思考了了另外一点:复用和专用要做平衡 。

4 复用和专用要做平衡

我当时写的那个接口 getUserByConditions ,是支持四种不同参数的查询,同样也是为了省时间,快点出活。

后来,随着我工作经验的日益丰富,我的编程习惯也慢慢发生了改变,对于业务需求明确的场景,我更多的倾向于将通用接口拆分成专用接口。

比如 getUserByConditions 可以拆分成如下四个接口 ,

  • 按照用户 ID 查询用户信息

  • 按照用户昵称查询用户信息

  • 按照手机号查询用户信息

  • 按照用户名查询用户信息

比如按照用户 ID 查询用户信息 , SQLMAP 就简化为:

9c9c50ec8a2babb07f090e0ef0c9a8ae.png

通过这样的拆分,我们的接口设计更加细粒度,也更容易维护 , 同时也可以规避 where 1 =1 产生的不确定性(虽然我做了后端校验,依然存在不确定性)。

有的同学会有疑问:假如拆分得太细,会不会增加我编写接口和 SQLMap 的工作量 ?

笔者的思路是:定制自己的代码生成器,将生成的 SQLMap  、Mapper 保证更细的颗粒度。

5 防御性编程意识

笔者刚入行的时候,只是机械性的完成任务,并没有思考代码后面的资源占用,以及有没有可能产生恶劣的影响。

随着见识更多的系统,学习开源项目,笔者慢慢培养了一种习惯:

  • 这段代码会占用多少系统资源

  • 如何规避风险 ,做好预防性编程。

其实,这和玩游戏差不多 ,在玩游戏的时,我们经常说一个词,那就是意识。

ab673d4a290f13c246cd80fc8953d045.jpeg

上图,后裔跟墨子在压对面马可蔡文姬,看到小地图中路铠跟小乔的视野,方向是往下路来的,这时候我们就得到了一个信息。

知道对面的人要来抓,或者是协防,这种情况我们只有两个人,其他的队友都不在,只能选择避战,强打只会损失两名“大将”。

通过小地图的信息,并且想出应对方法,就是叫做“猜测意识”。

编程也是一样的,我们思考代码可能产生的系统资源占用,以及可能存在的风险,并做好防御性编程,就是编程的意识 。

6 写到最后

人生第一次线上 OOM 事故,因我在使用 Mybatis 动态 SQL 时,没有做后端校验而出现,造成了比较坏的影响。

在后面的职业生涯里面,为了规避生产环境的事故,我试着打磨自己的编程思维,比如做好后端校验 、平衡好复用和专用接口 、培养防御性编程的意识 。

絮絮叨叨这么多,大家可能觉得我小题大做了,但事实是,类似我这样的事故层出不穷,上周我又目睹了一起。

IT 世界有了那么多框架,好像我们依然写不好代码,我有点沮丧。


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,“长按”或“扫描”下方二维码噢:

12cd230e456dd5664edaaa12d25dbe86.png

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

91f61b38ec7e99feceddf78a5b9b1147.png

a26d44e7ac1485a3b32f97ac57eb9066.png59ab66d1dbf4eb2e7ac6f863a0c8d005.png085c1bc8fa8b7cb49965a006c77cc5e9.png90994edf203209e8c3707998c1a89e8a.png

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
Python基础语法与最佳实践【python基础篇】 本文全面介绍了Python基础语法与最佳实践,涵盖变量与数据类型、控制流、函数、模块与包等核心概念。通过实际代码示例展示了条件语句、循环结构、函数定义及模块导入的基本用法。在最佳实践部分,重点讲解了PEP 8代码风格规范、异常处理技巧、列表推导式、上下文管理器、文档字符串编写以及enumerate和zip的高效使用。这些内容既适合Python初学者掌握基础语法,也能帮助有经验的开发者编写更规范、高效、可维护的代码。文章强调遵循Python官方推荐实践,通过合理运用语言特性提升代码质量。 阅读详情

相关推荐

UFS 3.1协议分析(第五章) -- UFS协议栈

ContentsUFS顶层架构应用层UFS命令集UFS 设备管理器UFS任务管理器传输层互连层 UFS顶层架构     UFS基于SCSI SAM架构模型定义了一个完整的协议栈,从上到下依次为应用层、传输层、数据链路层、物理层。UFS使用MIPI联盟的UniPro作为数据链路层和MIPI的M-PHY作为物理层,两者合起来称之为互连层(UFS InterConnect Layer) 应用层     应用层包括UFS命令集、设备管

Frank_sample的专栏 7366

使用ibatis的sql语句

无

m0_67379678的博客 960

保姆级教程:用rosbag录制和回放你的第一个ROS机器人数据(附C++/Python代码)

本文提供了一份详细的ROS机器人数据录制与回放教程,涵盖从命令行操作到C++/Python编程实现的全流程。通过rosbag工具,开发者可以高效记录和回放机器人运行时的传感器数据和控制指令,适用于故障复现、算法调试等多种场景。教程还包含高级技巧如时间同步和大文件处理,帮助用户快速掌握ROS数据管理核心技能。

weixin_29313239的博客 283

ibatis动态SQL语句

检查属性是否不为 null。比较属性值和静态值或另一个属性值是否相等。比较属性值和静态值或另一个属性值是否不相等。

2401_83329718的博客 1120

【eNSP 华为模拟器】单臂路由实战:从原理到配置全解析

本文详细解析了单臂路由技术,通过华为eNSP模拟器从原理到配置进行实战教学。文章阐述了单臂路由如何利用路由器单物理接口创建多个子接口,实现不同VLAN间通信,并提供了完整的操作步骤、配置命令及排错方法,帮助网络工程师掌握这一经典网络技术。

696

ibatis中常见的sql写法和注意事项

全文概要本文主要着手于Apache推出的一种轻量级对象关系映射(ORM)框架--ibatis,介绍一些常见的sql配置写法和注意事项,欢迎补充!本文主要内容如下:insert操作返回主键处理clob大数据类型调用procedure调用function传参为List返回结果为Listinsert操作返回主键ibatis中有针对插入数据返回主键的配置,在实际开发中是很常见的,配置写法如下:<in...

tianmlin1的博客 3503

Nginx下ModSecurity模块安装详细教程

本文提供了在Nginx 1.28.0上安装ModSecurity v3的完整教程。首先需安装编译依赖,然后从源码编译安装ModSecurity库并设置优化参数。接着编译Nginx动态模块并配置加载。核心配置包括设置规则引擎、日志路径及性能优化参数。安装OWASP核心规则集后,在Nginx站点配置中启用ModSecurity。最后测试规则有效性并给出性能优化建议,如规则排除、精简规则集等。整个过程包含详细的命令和配置示例,确保安全防护功能正常运作。

深山技术宅的博客 1781

ibatis常用16条SQL语句

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34009794的博客 321

python中使用squarify包可视化treemap图:为treemap图添加标题并自定义标题的字体大小、自定义设置treemap中标签字体的大小、添加数值数值标签、自定义设置边框的色彩

python中使用squarify包可视化treemap图:treemap将分层数据显示为一组嵌套矩形自定义设置每一个数据格的颜色、添加数值数值标签、自定义设置边框的色彩、自定义设置边框线条的粗细、为treemap图添加标题并自定义标题的字体大小、自定义设置treemap中标签字体的大小

data+scenario+science+insight 1061

链接文件及功能安全:基于Tasking的LSL链接文件知识点梳理及实际应用分析

本文旨在记录研究链接文件时所遇到的问题及个人理解,以便日后查阅。在探索过程中,我遇到了诸多问题,同时对链接文件有了初步的认识。通过记录这些问题与理解,我希望能够为后续的研究提供清晰的思路和有价值的参考。这不仅是对研究过程的总结,更是对未来学习和实践的有力支持。

梦想技术家 1098

iBatis动态条件查询

(1)实例一:          动态条件分页查询 -->         sql id="sql_count">                 select count(*)         sql>         sql id="sql_select">                 select *         sql>         s

Rambo的博客 2061

学Simulink——线控转向(Steer‑By‑Wire, SBW)路感模拟与回正控制仿真

本文详细介绍了线控转向(SBW)系统的Simulink建模方法,重点讲解了路感模拟与回正控制的实现原理。文章首先分析了SBW系统结构,建立了方向盘和前轮的动力学方程;随后分步骤演示了Simulink建模过程,包括方向盘二阶动力学、前轮位置闭环控制、路感反馈计算等核心模块;最后通过仿真验证了转向跟随性能、路感反馈效果和自动回正功能。文中还提供了工程实现的关键参数和注意事项,为开发真实的SBW系统提供了实用指导。该模型可扩展应用于主动转向、故障注入等高级功能开发。

xiaoheshang_123的博客 39

聊聊 Mybatis 动态 SQL?

如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。Mybatis 借助功能强大 OGNL 表达式,可以根据参数条件,动态生成执行 SQL。使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。这条语句提供了可选的查询博客文章列表 ,如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 博客都会返回。

m0_73735578的博客 372

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

聊聊Mybatis的动态Sql之SqlSource

这篇文章讲了SqlSource的接口和它的几个实现类,其中DynamicSqlSource类和RawSqlSource类最最终生成StaticSqlSource类,由StaticSqlSource类调用getBoundSql()方法来创建BoundSql类,DynamicSqlSource是解析动态sql的类,RawSqlSource是解析静态sql的类,在程序启动的时候就生成sql了。

Candyz7的博客 627

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

聊聊MyBatis中的动态SQL(附实例演示)

首先,动态SQL是Mybatis的强大特性之一。利用这一特性可以让我们摆脱根据不同条件拼接SQL语句的痛苦(如拼接SQL语句要确保不能忘记添加必要的空格,还要注意去掉列表里最后一个列名的逗号等等) 这个标签提供了可选的查找文本功能根据是否传入相应的字段来确定要不要把if标签内的语句拼接到主SQL语句。实例: 数据库表: 对应实体类: @Alias("blog") @Data @AllArgsConstructor @NoArgsConstructor public class blog ..

weixin_44107140的博客 858

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

聊聊Mybatis的动态Sql之这三个SqlNode同样重要

这篇文章主要讲了解析foreach标签的类ForEachSqlNode、解析标签的VarDeclSqlNode类和解析choose标签的ChooseSqlNode类,同时介绍这三个类的apply()方法的实现,这三个类都是SqlNode的实现类,都是对xml文件中的标签解析成的对象,这些SqlNode对象会被解析处理成SqlSource接口和它的实现类,供数据库执行。

ch98000的博客 313

Mybatis—动态SQL之常用标签的使用

前言 今天我们来聊聊Mybatis的动态SQL的使用,动态SQL可以说是mybatis的核心,可以对SQL语句进行灵活操作,通过表达式进行判断,对SQL进行灵活拼接,组装。在实际项目开发中,我们还可以将在业务层处理的逻辑转移到SQL中进行处理,因为SQL语句通常会比程序代码执行的要快,毕竟数据库是专门做数据处理和计算的嘛。 我们以 student_score 表为例来说明: if+where 语句 SQL语句中 < if > 标签和代码中的 if 语句作用是一样的,都是条件判断。加上 if 标

玲珑骰子安红豆,入骨相思知不知 1048

mybatis choose when 多条件_Mybatis—动态SQL详解

前言今天我们来聊聊Mybatis的动态SQL的使用,动态SQL可以说是mybatis的核心,可以对SQL语句进行灵活操作,通过表达式进行判断,对SQL进行灵活拼接,组装。在实际项目开发中,我们还可以将在业务层处理的逻辑转移到SQL中进行处理,因为SQL语句通常会比程序代码执行的要快,毕竟数据库是专门做数据处理和计算的嘛。我们以 student_score 表为例来说明:if+where ...

weixin_39813574的博客 1万+

MyBatis中这样使用动态SQL,同事直呼666!

如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。Mybatis 借助功能强大 OGNL 表达式,可以根据参数条件,动态生成执行 SQL。使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。这条语句提供了可选的查询博客文章列表 ,如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 博客都会返回。

m0_73735578的博客 520

MyBatis条件查询效率对比:传统写法vs动态SQL

更糟糕的是,字符串拼接容易导致SQL注入风险,需要额外注意参数过滤。在数据库查询中,条件判断是常见的需求,其中大于等于(>=)操作符使用频率很高。今天我们就来聊聊在MyBatis中实现大于等于条件查询的两种方式:传统Java拼接SQL和动态SQL,看看它们在实际开发中的表现差异。虽然简单场景下两种方式差别不大,但随着项目规模扩大,动态SQL的价值会越来越明显。传统方式:Java代码中需要大量字符串拼接,一个复杂查询可能占用数十行代码,修改时需要同时改动Java和SQL部分。简单固定条件:两种方式都可以。

AmberLeopard26的博客 662

mybatis原理:参数解析与SQL动态组装过程

mybatis执行sql之前,需要经过参数解析、sql动态组装等过程,本文主要聊聊mybatis的: (1)参数解析原理及其过程 (2)sql动态组装原理及其过程 一、数据准备 1.实体类,省略了set、get方法 public class User { private String id; private String username; private String password; private Integer isValid...

qiuxinfa123的博客 2483

MyBatis动态SQL大揭秘:让你的SQL“活”起来!

MyBatis的动态SQL通过if、where、set、trim、foreach、sql六大标签,完美解决了传统JDBC拼接SQL的痛点,让我们的SQL既灵活又易维护!if:条件判断,想拼就拼where:智能WHERE,自动去AND/ORset:智能SET,自动去逗号trim:全能修剪,前后都能加/去foreach:集合遍历,批量操作神器sql:代码复用,减少重复劳动学会了动态SQL,你会发现MyBatis开发原来这么爽!赶紧去试试吧!

smile_WangDuoduo的博客 612

Mybatis:缓存,动态SQL,注解SQL以及动态标签使用

1 转义字符 字符 转义 描述 < &lt; 小于 <= &lt;= 小于等于 > &gt; 大于 >= &gt;= 大于等于 <> &lt;&gt; 不等于 & &amp; ' &apos; " &quot; 2 一级...

229
上一篇: Redis 鸟枪换炮了
下一篇: 一天干了多少活儿,摸了多少鱼,这个工具一目了然给你统计出来
公众号-芋道源码
博客等级 码龄10年 1627粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值