Mybatis的特性详解——动态SQL

article/2025/8/21 14:31:39

Mybatis的特性详解——动态SQL

  • 前言
  • 一、动态sql的元素
  • 1.MyBatis if标签:条件判断
  • 2.MyBatis choose、when和otherwise标签
  • 3.MyBatis where标签
  • 4.MyBatis set标签
  • 5.MyBatis foreach标签
  • 6.MyBatis bind标签
  • 7.MyBatis trim标签
  • 仰天大笑出门去,我辈岂是蓬蒿人


前言

动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它类似的框架中,开发人员通常需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询。

动态 SQL 只有几个基本元素,与 JSTL 或 XML 文本处理器相似,十分简单明了,大量的判断都可以在 MyBatis 的映射 XML 文件里配置,以达到许多需要大量代码才能实现的功能。

好处::动态 SQL 大大减少了编写代码的工作量,更体现了 MyBatis 的灵活性、高度可配置性和可维护性。


一、动态sql的元素

MyBatis 的动态 SQL 包括以下几种元素,如下表所示
在这里插入图片描述

1.MyBatis if标签:条件判断

MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。使用 if 标签可以节省许多拼接 SQL 的工作,把精力集中在 XML 的维护上。if 语句使用方法简单,常常与 test 属性联合使用。
语法如下:

<if test="判断条件">SQL语句
</if>

当判断条件为 true 时,才会执行所包含的 SQL 语句。
最常见的场景是在 if 语句中包含 where 子句,例如。

<select id="selectAllBaseData" resultMap="myResult">select id,name from baseData<if test="name != null">where name like #{name}</if>
</select>

以上代表表示根据name去查找相应的信息,但是name是一个可填可不填的条件,不填写的时候不作为查询条件。

可多个 if 语句同时使用。以下语句表示为可以按照 name 或者 id 进行模糊查询。如果您不输入,则返回所有的记录。但是,如果你传递了任意一个参数,它就会返回与给定参数相匹配的记录:

<select id="selectAllBaseData" resultMap="myResult">select id,name from baseData<if test="name != null">where name like #{name}</if><if test="id != id">AND id like #{id}</if>
</select>

2.MyBatis choose、when和otherwise标签

MyBatis 中动态语句 choose-when-otherwise 类似于 Java 中的 switch-case-default 语句。由于 MyBatis 并没有为 if 提供对应的 else 标签,如果想要达到<if>...<else>...</else> </if> 的效果,可以借助 <choose>、<when>、<otherwise> 来实现。
动态语句 choose-when-otherwise 语法如下。

<choose><when test="判断条件1">SQL语句1</when ><when test="判断条件2">SQL语句2</when ><when test="判断条件3">SQL语句3</when ><otherwise>SQL语句4</otherwise>
</choose>

choose 标签按顺序判断其内部 when 标签中的判断条件是否成立,如果有一个成立,则执行相应的SQL 语句,choose 执行结束;
如果都不成立,则执行 otherwise 中的 SQL 语句。
这类似于 Java 的 switch 语句;

  • choose 为 switch,
  • when 为 case,
  • otherwise 则为 default。

示例

以下示例要求:
当网站名称不为空时,只用网站名称作为条件进行模糊查询;
当网站名称为空,而网址不为空时,则用网址作为条件进行模糊查询;
当网站名称和网址都为空时,则要求网站年龄不为空.

<mapper namespace="net.biancheng.mapper.WebsiteMapper"><select id="selectWebsite">SELECT id,name,url,age,countryFROM website WHERE 1=1<choose><when test="name != null and name !=''">AND name LIKE CONCAT('%',#{name},'%')</when><when test="url != null and url !=''">AND url LIKE CONCAT('%',#{url},'%')</when><otherwise>AND age is not null</otherwise></choose></select>
</mapper>

这样 MyBatis 就会根据参数的设置进行判断来动态组装 SQL,以满足不同业务的要求。远比 Hibernate 和 JDBC 中大量判断 Java 代码要清晰和明确。

3.MyBatis where标签

where 标签

where 标签主要用来简化 SQL 语句中的条件判断,可以自动处理 AND/OR 条件,语法如下

<where><if test="判断条件">AND/OR ...</if>
</where>

if 语句中判断条件为 true 时,where 关键字才会加入到组装的 SQL 里面,否则就不加入。where 会检索语句,它会将 where 后的第一个 SQL 条件语句的 AND 或者 OR 关键词去掉。

示例

<select id="selectWebsite" resultType="net.biancheng.po.Website">select id,name,url from website<where><if test="name != null">AND name like #{name}</if><if test="url!= null">AND url like #{url}</if></where>
</select

4.MyBatis set标签

在 Mybatis 中,update 语句可以使用 set 标签动态更新列。set 标签可以为 SQL 语句动态的添加 set 关键字,剔除追加到条件末尾多余的逗号。 代码如下。

    <!--使用set元素动态修改一个网站记录 --><update id="updateWebsite">UPDATE website<set><if test="name!=null">name=#{name},</if><if test="url!=null">url=#{url},</if></set>WHERE id=#{id}</update>

5.MyBatis foreach标签

对于一些 SQL 语句中含有 in 条件,需要迭代条件集合来生成的情况,可以使用 foreach 来实现 SQL 条件的迭代。
Mybatis foreach 标签用于循环语句,它很好的支持了数据和 List、set 接口的集合,并对此提供遍历的功能。语法格式如下。

<foreach item="item" index="index" collection="list|array|map key" open="(" separator="," close=")">#{item}
</foreach>

foreach 标签主要有以下属性,说明如下:

  • item:表示集合中每一个元素进行迭代时的别名。
  • index:指定一个名字,表示在迭代过程中每次迭代到的位置。
  • open:表示该语句以什么开始(既然是 in 条件语句,所以必然以(开始)。
  • separator:表示在每次进行迭代之间以什么符号作为分隔符(既然是 in 条件语句,所以必然以,作为分隔符)。
  • close:表示该语句以什么结束(既然是 in 条件语句,所以必然以)开始)。

使用 foreach 标签时,最关键、最容易出错的是 collection 属性,该属性是必选的,但在不同情况下该属性的值是不一样的,主要有以下 3 种情况:

  • 如果传入的是单参数且参数类型是一个 List,collection 属性值为 list。
  • 如果传入的是单参数且参数类型是一个 array 数组,collection 的属性值为 array。
  • 如果传入的参数是多个,需要把它们封装成一个 Map,当然单参数也可以封装成 Map。Map 的 key 是参数名,collection 属性值是传入的 List 或 array 对象在自己封装的 Map 中的 key。

示例

修改array里面id为这些的数据status改为0

  update project set status = 0 where id in<foreach item="id" collection="array" open="(" separator="," close=")">#{id}</foreach>

注意事项:在使用 foreach 标签时,应提前预估一下 collection 对象的长度。因为大量数据的 in 语句会影响性能,且还有一些数据库会限制执行的 SQL 语句长度。

6.MyBatis bind标签

每个数据库的拼接函数或连接符号都不同,例如 MySQL 的 concat 函数、Oracle 的连接符号“||”等。这样 SQL 映射文件就需要根据不同的数据库提供不同的实现,显然比较麻烦,且不利于代码的移植。MyBatis 提供了 bind 标签来解决这一问题。
bind 标签可以通过 OGNL 表达式自定义一个上下文变量。
比如,按照网站名称进行模糊查询,SQL 映射文件如下。

<select id="selectWebsite" ><bind name="pattern" value="'%'+_parameter+'%'" />SELECT id,name,url,age,countryFROM websiteWHERE name like #{pattern}
</select>

bind 元素属性如下:

  • value:对应传入实体类的某个字段,可以进行字符串拼接等特殊处理。
  • name:给对应参数取的别名。

以上代码中的“_parameter”代表传递进来的参数,它和通配符连接后,赋给了 pattern,然后就可以在 select 语句中使用这个变量进行模糊查询,不管是 MySQL 数据库还是 Oracle 数据库都可以使用这样的语句,提高了可移植性。
大部分情况下需要传递多个参数,下面为传递多个参数时 bind 的用法示例。

示例

//mapper文件中入参
public List<User> selectUser(User user);
-- xml中
<select id="selectUser" resultType="User"><bind name="pattern_name" value="'%'+name+'%'" /><bind name="pattern_url" value="'%'+url+'%'" />SELECT id,name,url,age,countryFROM UserWHERE name like #{pattern_name}AND url like #{pattern_url}
</select>

7.MyBatis trim标签

在 MyBatis 中除了使用 if+where 实现多条件查询,还有一个更为灵活的元素 trim 能够替代之前的做法。
trim 一般用于去除 SQL 语句中多余的 AND 关键字、逗号,或者给 SQL 语句前拼接 where、set 等后缀,可用于选择性插入、更新、删除或者条件查询等操作。trim 语法格式如下。

<trim prefix="前缀" suffix="后缀" prefixOverrides="忽略前缀字符" suffixOverrides="忽略后缀字符">SQL语句
</trim>

trim 中属性说明如下
在这里插入图片描述示例

<select id="selectUser" resultType="User">SELECT id,name,url,age,countryFROM User<trim prefix="where" prefixOverrides="and"><if test="name != null and name !=''">AND name LIKE CONCAT ('%',#{name},'%')</if><if test="url!= null">AND url like concat ('%',#{url},'%')</if></trim>
</select>

仰天大笑出门去,我辈岂是蓬蒿人


http://chatgpt.dhexx.cn/article/1ktR2a4p.shtml

相关文章

Java编程基础八股文(背诵版)

Java语言具有哪些特点&#xff1f; Java为纯面向对象的语言。它能够直接反应现实生活中的对象。 具有平台无关性。java利用Java虚拟机运行字节码&#xff0c;无论是在Windows、Linux还是MacOS等其它平台对Java程序进行编译&#xff0c;编译后的程序可在其它平台运行。 Java为…

Java编程基础篇

目录 计算机、程序和Java概述计算机组成 基本程序设计标识符数值数据类型格式化控制台输出输入输出重定向输入重定向输出重定向输入输出重定向方法重载变量的范围 数组声明数组变量创建数组初始化数组可边长参数二维数组静态变量、常量和方法静态变量 限定字符串StringBuilder和…

Java 基础编程入门

一、什么是Java Java是一种编程语言二、应用场景 非windows平台下互联网环境的开发首选三、Java语言特点 1、应用面广 2、简单易学(相对于C/C) 3、面向对象(更符合我们看待事物的特点) 4、跨平台(一处编译&#xff0c;处处运行) 5、多线程(提升系统性能) 单线…

JAVA的编程基础(上)

1. JAVA的基本语法 1.1 注释 单行注释&#xff1a;// 多行注释&#xff1a;/* */ 文档注释&#xff1a;/** */ 注意&#xff1a;单行注释可以嵌套&#xff0c;多行注释和文档注释不可以嵌套 1.2 关键字 含义&#xff1a;在编程语言中&#xff0c;已经被赋予一些特殊含义…

Java编程基础(1)

1.Java基本语法 &#xff08;1&#xff09;Java程序的基本格式&#xff1a; 修饰符 class 类名 { 程序代码 } 如果Java程序要运行&#xff0c;则必须要有main方法&#xff0c;main方法是程序运行的入口 格式&#xff1a; 修饰符 class 类名{ public static void main&…

Java编程基础之网络编程

网络编程 文章目录 网络编程概述C/S和B/S网络通信协议网络编程要素 IP类UDP协议数据传输发送端接收端udp数据传输丢失问题 TCP概述Socket客户端ServerSocket服务端Socket**服务器代码**客户端代码 文件上传实现客户端服务端多线程版 概述 C/S和B/S 网络通信协议 协议:protoco…

java编程基础(一)二进制

文章目录 二进制面试题bit 和 bytejava 中的 byte 类型java 中 byte 类型表示正数&#xff1a;java 中 byte 类型表示负数&#xff1a; 四种整数类型的最小和最大值二进制和十进制的互转练一练java 代码中直接写二进制字面值代码仓库 二进制 对于任何已知类型的传统计算机而言…

Java 基础

Java 基础知识点整理 Java 语言是一种优秀的编程语言&#xff0c;由 C 语言、C 语言发展而来。Java 语言提供了一些有效的新特性&#xff0c;使得使用 Java 比 C 更容易写出“无错代码”。 Java特性和优点 面向对象编程的思想&#xff0c;更简单有效&#xff0c;Java 省略了 …

Java编程基础②

Java编程基础 Java中的注释Java中的标识符Java中的关键字Java中的常量常量类型定义常量 java中的变量变量的定义及其数据类型变量的类型转换变量的作用域 java运算符算术运算符赋值运算符比较运算符逻辑运算符位运算符运算符的优先级 java流程控制语句if条件语句switch条件语句…

第二章 Java编程基础

第二章 Java编程基础 目录 一&#xff0e; Java基本语法1. 基本格式2. 注释3. 标识符4. 关键字5. 常量 二&#xff0e; 变量1. 定义2. 数据类型3. 整数类型变量4. 浮点类型变量5. 字符类型变量6. 布尔类型变量7. 类型转换8. 自动提升9. 变量作用域 三&#xff0e; 运算符1. 算数…

【JAVA】1.编程基础

1.Java基本语法 JAVA基本格式&#xff1a; 修饰符 class 类名{ 程序代码 } public class java {public static void main(String[] args) {System.out.println("HelloWorld"); } public static void main(String[] args) {} &#xff08;对于初学者来说这个部分必…

第二章Java编程基础

一、填空题 1&#xff0e;Java程序代码必须放在一个类中&#xff0c;类使用class关键词定义。 2&#xff0e;Java中的注释有三类&#xff0c;分别是单行注释、多行注释、文档注释。 3&#xff0e;Java语言中&#xff0c;int类型所占存储空间为4个字节。 4&#xff0e;用于比…

Java基础 —— 编程入门

一、比特(bit)和字节(byte) 一个0或者一个1存储为一个比特(bit)&#xff0c;是计算机中最小的存储单位。计算机中是最基本的存储单元是字节(byte)。 每个字节由8个比特构成。 计算机就是一系列的电路开关。每个开关存在两种状态:关(off)和开(on)。如果电路是开的&#xff0c;它…

第二章:JAVA编程基础

目录 一&#xff1a;Java的基本语法格式 二&#xff1a;Java中的变量与常量 三&#xff1a;Java中的运算符 四&#xff1a;选择结构语句 五&#xff1a;循环结构语句 六&#xff1a;数组 一&#xff1a;Java的基本语法格式 1&#xff1a;语法格式 [修饰符] class 类名{…

Java编程基础知识(一)

目录 一.Java的基本语法 1.Java的基本语法格式 2.Java中的注释 3.Java中的关键字 Java中的标识符 二.Java中的常量与变量 1.常量 2.变量 三.Java中的运算符 四.数据输入 一.Java的基本语法 1.Java的基本语法格式 编写Java程序必须先声明一个类&#xff0c;然后再类中…

Java编程基础

目录 第一篇、Java编程基础 ❀Java中的属性名词 ❀Java数据类型 ❀转义字符 ❀&& 和 & 与 || 和 | ❀方法 第二篇、Java面向对象编程 ❀类和对象 ❀面向过程和面向对象的区别 ❀面向对象程序设计的主要特性 ❀类和对象概述 ❀对象的内存结构 ❀垃圾空间…

java编程基础(入门级)(超级完整版)

java基础编程&#xff08;入门&#xff09; 01基础知识 1.计算机基础 【1】进制 A.十进制转化二进制 除以2&#xff0c;求余数&#xff0c;商继续除以2&#xff0c;一直到0为止&#xff0c;从底下往上得到结果。 B.二进制转化十进制 1 | 1 | 0 | 0 2 3 ∣ 2 2 ∣ 2 1 ∣ 2 …

UFBGA176+25 封装尺寸图

下图是UFBGA17625 封装规格的参数&#xff0c;根据下图的参数&#xff0c;即可制作UFBGA17625 的PCB封装

电阻的封装规格

1.直插式电阻 卧式直插电阻的封装形式为AXIAL-xx(比如 AXIAL-0.3)&#xff0c;0.3为焊盘中心距&#xff0c;单位是英寸&#xff0c;1 inch 25.4 mm 1000mil。 M型&#xff0c;电阻两端折弯。金属膜直插电阻功率-封装-尺寸对应表 封装尺寸(inch)对应长度&#xff08;mm&#…

Allegro PCB封装表贴器件-0805电阻-实战-详细封装制作过程(一)

1.Allegro封装元素 使用Allegro制作PCB封装&#xff0c;首先我们需要了解Allegro封装组成的元素&#xff0c;由焊盘、外形、字符三要素组成&#xff0c;如图 1所示。 图 1 Allegro封装元素 2.表贴元器件 2.1 0805电阻 我们需从规格书获得0805电阻推荐焊盘尺寸&#xff0c;如图 …