当前位置: 首页 > news >正文

Spring学习笔记【8】

MyBatis 动态SQL

📖 目录

  • 动态SQL概述
  • if元素 - 条件判断
  • choose/when/otherwise元素 - 分支选择
  • trim元素 - 前后缀处理
  • where元素 - 智能条件处理
  • set元素 - 动态更新
  • foreach元素 - 集合遍历
  • bind元素 - 变量绑定
  • 总结

🔍动态SQL概述

动态SQL是MyBatis的核心特性之一,它能够根据不同条件动态生成SQL语句,解决了传统静态SQL在复杂业务场景下的局限性。

为什么需要动态SQL? 在实际开发中,我们经常遇到这样的场景:

  • 根据用户输入的不同条件进行查询
  • 批量操作时参数数量不确定
  • 更新操作时只更新有值的字段
  • 不同业务逻辑需要不同的SQL片段

动态SQL通过各种标签元素,让我们能够在XML映射文件中编写灵活的SQL逻辑,提高代码的复用性和可维护性。

了解动态SQL的重要性后,让我们从最基础的条件判断开始学习。

🔍if元素 - 条件判断

<if> 元素是动态SQL中最基础也是最常用的元素,用于根据条件决定是否包含某个SQL片段。

2.1 基本用法

<!-- 使用if元素,根据条件动态查询用户信息 -->
<select id="selectUserByIf" resultType="com.po.MyUser" parameterType="com.po.MyUser">select * from user where 1=1        <if test="uname != null and uname != ''">and uname like concat('%', #{uname}, '%')</if><if test="usex != null and usex != ''">and usex = #{usex}</if>
</select>

2.2 test属性详解

test 属性中可以使用的表达式:

  • 空值判断uname != nulluname == null
  • 字符串判断uname != ''uname == ''
  • 数值比较age > 18score >= 60
  • 逻辑运算andornot

注意事项:

  • 使用 1=1 作为基础条件,避免第一个条件前的 and 造成语法错误
  • 字符串类型建议同时判断 != null!= ''
  • 数值类型只需判断 != null

🔍choose/when/otherwise元素 - 分支选择

当需要在多个条件中选择一个执行时,使用 <choose> 元素,类似于Java中的 switch-case 语句。

3.1 基本结构

<!-- 使用choose、when、otherwise元素,根据条件动态查询用户信息 -->
<select id="selectUserByChoose" resultType="com.po.MyUser" parameterType="com.po.MyUser">select * from user where 1=1        <choose><when test="uname != null and uname != ''">and uname like concat('%', #{uname}, '%')</when><when test="usex != null and usex != ''">and usex = #{usex}</when><otherwise>and uid > 10</otherwise></choose>
</select>

3.2 执行逻辑

  • <choose> 相当于 switch
  • <when> 相当于 case,按顺序检查条件
  • <otherwise> 相当于 default,当所有 when 条件都不满足时执行

使用场景:

  • 多个互斥条件中选择一个
  • 设置默认查询条件
  • 根据不同条件使用不同的排序方式

🔍trim元素 - 前后缀处理

<trim> 元素提供了强大的前后缀处理能力,是处理动态SQL中最灵活的元素。

4.1 属性说明

<!-- 使用trim元素,根据条件动态查询用户信息 -->
<select id="selectUserByTrim" resultType="com.po.MyUser" parameterType="com.po.MyUser">select * from user      <trim prefix="where" prefixOverrides="and |or "><if test="uname != null and uname != ''">  and uname like concat('%', #{uname}, '%')</if><if test="usex != null and usex != ''">  and usex = #{usex} </if></trim>
</select>

属性详解:

  • prefix:在内容前添加指定前缀(如 “where”)
  • suffix:在内容后添加指定后缀
  • prefixOverrides:去除内容开头的指定字符(如 "and "、"or ")
  • suffixOverrides:去除内容结尾的指定字符(如 “,”)

4.2 应用场景

<!-- 动态插入语句 -->
<insert id="insertUser" parameterType="com.po.MyUser">insert into user<trim prefix="(" suffix=")" suffixOverrides=","><if test="uname != null">uname,</if><if test="usex != null">usex,</if><if test="uage != null">uage,</if></trim>values<trim prefix="(" suffix=")" suffixOverrides=","><if test="uname != null">#{uname},</if><if test="usex != null">#{usex},</if><if test="uage != null">#{uage},</if></trim>
</insert>

🔍where元素 - 智能条件处理

<where> 元素是 <trim> 的简化版本,专门用于处理查询条件

5.1 基本用法

<!-- 使用where元素,根据条件动态查询用户信息 -->
<select id="selectUserByWhere" resultType="com.po.MyUser" parameterType="com.po.MyUser">select * from user      <where><if test="uname != null and uname != ''">and uname like concat('%', #{uname}, '%')</if><if test="usex != null and usex != ''">and usex = #{usex}</if></where>
</select>

5.2 智能处理

<where> 元素会智能地处理以下情况:

  • 当包含内容为空时,不会生成 where 关键字
  • 自动去除开头的 andor
  • 只有当包含内容不为空时才生成 where 子句

等价的trim写法:

<trim prefix="where" prefixOverrides="and |or "><!-- 内容 -->
</trim>

🔍set元素 - 动态更新

<set> 元素专门用于动态更新操作,能够智能处理更新字段。

6.1 基本用法

<!-- 使用set元素,动态修改一个用户 -->
<update id="updateUserBySet" parameterType="com.po.MyUser">update user     <set><if test="uname != null">uname = #{uname},</if><if test="usex != null">usex = #{usex},</if><if test="uage != null">uage = #{uage},</if></set>where uid = #{uid}  
</update>

6.2 智能处理特性

  • 自动添加 SET 关键字
  • 自动去除最后一个多余的逗号
  • 防止生成空的 SET 子句

🔍foreach元素 - 集合遍历

<foreach> 元素用于遍历集合,常用于 IN 查询、批量插入等场景。

7.1 基本用法

<!-- 使用foreach元素,查询用户信息 -->
<select id="selectUserByForeach" resultType="com.po.MyUser" parameterType="List">select * from user where uid in     <foreach item="item" index="index" collection="list" open="(" separator="," close=")">#{item}</foreach>
</select>

7.2 属性详解

属性说明示例值
collection指定要遍历的集合类型list/array/map
item集合中每个元素的变量名item/user
index当前元素的索引位置index/i
open遍历开始时的拼接字符(
close遍历结束时的拼接字符)
separator元素之间的分隔符,

7.3 collection属性规则

collection的值取决于参数类型

  • 单个List参数collection="list"
  • 单个Array参数collection="array"
  • Map参数collection="map中的key"
  • 对象属性collection="对象.属性名"

🔍bind元素 - 变量绑定

<bind> 元素用于创建变量并绑定到上下文中,主要解决模糊查询中的SQL注入问题和数据库兼容性问题。

8.1 解决的问题

传统方式的问题:

  • 使用 ${} 拼接存在SQL注入风险
  • 不同数据库的字符串拼接函数不同(MySQL的concat、Oracle的||

8.2 基本用法

<!-- 使用bind元素进行模糊查询 -->
<select id="selectUserByBind" resultType="com.po.MyUser" parameterType="com.po.MyUser"><!-- bind中uname是com.po.MyUser的属性名,paran_uname是自定义变量名 --><bind name="paran_uname" value="'%' + uname + '%'"/>select * from user where uname like #{paran_uname}  
</select>

8.3 表达式语法

<bind>value 属性支持:

  • 字符串拼接'%' + name + '%'
  • 条件表达式age > 18 ? '成年' : '未成年'
  • 对象属性访问user.name + '(' + user.id + ')'
  • 方法调用name.toLowerCase()

🔍总结

MyBatis动态SQL通过不同的标签元素实现了灵活的SQL生成:

元素作用适用场景核心特性
<if>条件判断根据条件包含SQL片段简单条件判断
<choose>分支选择多个条件中选择一个类似switch-case
<trim>前后缀处理灵活的前后缀管理高度可定制化
<where>条件子句动态生成WHERE条件智能处理and/or
<set>更新子句动态UPDATE操作智能处理逗号
<foreach>集合遍历批量操作、IN查询支持多种集合类型
<bind>变量绑定模糊查询、变量处理防SQL注入,跨数据库兼容

最后希望这份笔记能给你带来微薄的帮助!🎉

http://www.lryc.cn/news/575059.html

相关文章:

  • 【嘉立创EDA】PCB 如何按板框轮廓进行铺铜
  • JVM调优实战 Day 6:JVM性能监控工具实战
  • Redis大规模Key遍历实战:性能与安全的最佳实践
  • 前端中的 CI/CD 教程详解(附实践方案)
  • 初学python的我开始Leetcode题10-3
  • Node.js-fs模块
  • 【Linux】Shell 脚本编程——条件测试与比较
  • python的易家宜超市云购物系统
  • 无人机灯光驱动模块技术解析
  • 京东正式开源 Taro on HarmonyOS C-API 版本,为鸿蒙应用跨端开发提供高性能框架
  • Xcode缓存清除
  • 【CUDA调优指南】缓存访存流程
  • Jenkins CLI 使用方法介绍
  • Jenkins JNLP与SSH节点连接方式对比及连接断开问题解决方案
  • 力扣2040两个有序数组的第K小乘积
  • Docker、Docker composer与Docker desktop
  • 英文摘要给成中文摘要模型
  • 探索解析C++ STL中的 list:双向链表的高效实现与迭代器
  • NCCN Guidelines Navigator:数智化工具引领肿瘤精准治疗新纪元
  • 八股文——JAVA基础:说一下C++与java的区别
  • 企业内部安全组网技术解析:安全通道选型、零信任架构与数据合规加密防护
  • 【AI论文】拖拽式大型语言模型:零样本提示到权重的生成
  • 打造灵活强大的PDF解析管道:从文本提取到智能分块的全流程实战
  • 从零构建 gRPC 跨语言通信:C++ 服务端与 C# 客户端完整指南
  • 数据库1.0
  • OceanBase向量检索在货拉拉的探索和实践
  • 【智能协同云图库】智能协同云图库第二弹:用户管理系统后端设计与接口开发
  • Mysql使用窗口函数查询
  • 基于MATLAB的BP神经网络的心电图分类方法应用
  • 云原生与人工智能的融合:从弹性架构到智能运维的IT新范式