(十三)Mybatis动态SQL各种标签的用法详解

2023-11-12

这篇文章主要讲述Mybatis动态SQL各种标签的用法详解,学习Mybatis动态sql看这一篇博客足够了。

什么是静态SQL?

如果嵌入了SQL语句,而这个SQL语句的主体结构已经明确,例如在Java的一段代码中有一个待执行的SQL“select * from t1 where c1>5”,在Java编译阶段,就可以将这段SQL交给数据库管理系统去分析,数据库软件可以对这段SQL进行语法解析,生成数据库方面的可执行代码,这样的SQL称为静态SQL。

什么是动态SQL?

如果嵌入的SQL没有明确给出,如在Java中定义了一个字符串类型的变量sql:String sql;,然后采用preparedStatement对象的execute方法去执行这个sql,该sql的值可能等于从文本框中读取的一个SQL或者从键盘输入的SQL,但具体是什么,在编译时无法确定,只有等到程序运行起来,在执行的过程中才能确定,这种SQL叫做动态SQL。MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作。

动态SQL标签详解

IF标签的用法

在开发中有时候我们会有很多条件查询,而这些条件我们可填也可不填,这个时候我们可以使用IF标签来解决。
test:判断表达式(OGNL),OGNL语法可以参照官方文档。

 <select id="getEmpsByConditionIf" resultType="com.gzl.mybatis.bean.Employee">
 	select * from tbl_employee where
	 	<if test="id!=null">
	 		id=#{id}
	 	</if>
	 	<if test="lastName!=null">
	 		and last_name = #{lastName}
	 	</if>
 </select>

where标签的用法

针对于上面的sql写法,假如id传值为空,会直接出现下面的sql语法错误,这个时候可以用where标签。where标签可以帮我们去掉前面多余的and,切记他只会去掉前面的,假如and写在后面是不行的。

select * from tbl_employee where and last_name like ?
<select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
	select * from tbl_employee
	<where>
	 	<if test="id!=null">
	 		id=#{id}
	 	</if>
	 	<if test="lastName!=null">
	 		and last_name like #{lastName}
	 	</if>
	</where>
</select>

这个时候会发现即使id值不传只传lastName值,他会把lastName里面的and给去掉。
失效示例:在这种情况是没有用的。

<if test="lastName!=null">
	last_name like #{lastName} and
</if>

在实际开发当中还有一种比较省事的方法,也可以避免这种问题,那就是直接where 1=1

<select id="getEmpsByConditionIf" resultType="com.gzl.mybatis.bean.Employee">
	select * from tbl_employee where 1=1
	 	<if test="id!=null">
	 		and id=#{id}
	 	</if>
	 	<if test="lastName!=null">
	 		and last_name like #{lastName}
	 	</if>
</select>

trim标签的用法

trim可以帮我们完成后面多出的and或者or where标签不能解决,还可以用来切除字符串等等。
trim一共给我们提供了四个属性:
prefix:前缀,prefix给拼串后的整个字符串加一个前缀 。
prefixOverrides:前缀覆盖,去掉整个字符串前面多余的字符
suffix:后缀,suffix给拼串后的整个字符串加一个后缀
suffixOverrides:后缀覆盖:去掉整个字符串后面多余的字符

示例:用prefix前缀和suffixOverrides后缀覆盖来替代了where条件,这样也可以避免多个and报错问题。对于我们来说只需要知道他的这几个属性就行了,实际开发当中根据业务场景来进行完成一些特定功能。

<select id="getEmpsByConditionTrim" resultType="com.gzl.mybatis.bean.Employee">
 	select * from tbl_employee
 	<!-- 自定义字符串的截取规则 -->
 	<trim prefix="where" suffixOverrides="and">
 		<if test="id!=null">
	 		id=#{id} and
	 	</if>
	 	<if test="lastName!=null">
	 		last_name like #{lastName} and
	 	</if>
	 </trim>
 </select>

choose的用法

和case when功能差不多,都是只会走一种,不管when条件里面有几个满足了,都只走第一个,如果when所有条件都没有满足,就会走otherwise。

<select id="getEmpsByConditionChoose" resultType="com.gzl.mybatis.bean.Employee">
	select * from tbl_employee 
	<where>
		<!-- 如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个 -->
		<choose>
			<when test="id!=null">
				id=#{id}
			</when>
			<when test="lastName!=null">
				last_name like #{lastName}
			</when>
			<otherwise>
				gender = 0
			</otherwise>
		</choose>
	</where>
</select>

set标签的用法

修改的时候有时候我们只想修改表当中的一部分属性,而另一部分属性并不想改,我们传的空,这个时候可以使用set。
有的人该说了我光用 if 标签不就行了,这个是不行的,光用if条件假如gender属性传的为空,这个时候sql后面就会多个逗号,就会报错的。set标签主要就是可以帮我们把后面多余的逗号去掉。用trim也是可以的。

<update id="updateEmp">
	<!-- Set标签的使用 -->
	update tbl_employee 
	<set>
		<if test="lastName!=null">
			last_name=#{lastName},
		</if>
		<if test="email!=null">
			email=#{email},
		</if>
		<if test="gender!=null">
			gender=#{gender}
		</if>
	</set>
	where id=#{id} 
</update>

foreach标签的用法

foreach循环遍历的意思,一般可用于查询,或者批量新增等功能。
foreach一共有六个属性:

collection:指定要遍历的集合:list类型的参数会特殊处理封装在map中,map的key就叫list
item:将当前遍历出的元素赋值给指定的变量
separator:每个元素之间的分隔符
open:遍历出所有结果拼接一个开始的字符
close:遍历出所有结果拼接一个结束的字符
index:索引。遍历list的时候是index就是索引,item就是当前值
遍历map的时候index表示的就是map的key,item就是map的值

使用foreach接口传值方式,List数组。

public List<Employee> getEmpsByConditionForeach(@Param("ids")List<Integer> ids);

多个查询

<select id="getEmpsByConditionForeach" resultType="com.gzl.mybatis.bean.Employee">
	select * from tbl_employee
	<foreach collection="ids" item="item_id" separator=","
		open="where id in(" close=")">
		#{item_id}
	</foreach>
</select>

当list传两个数据的时候,执行出来的sql语句:

select * from tbl_employee where id in( ? , ? )

bind标签的用法

他的主要作用就是可以将后台传过来的参数进行特殊处理,并且可以多处调用。

<select id="getEmpsTestInnerParameter" resultType="com.gzl.mybatis.bean.Employee">
	<!-- bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值 -->
	<bind name="lastName" value="'%'+lastName+'%'"/>
	<if test="_databaseId=='mysql'">
		select * from tbl_employee
		<if test="_parameter!=null">
			where last_name like #{lastName}
		</if>
	</if>
 </select>

sql标签的用法

一般用来封装可重用的sql,然后我们可以使用include标签来进行调用。

<sql id="insertColumn">
	<if test="id!=null">
		id=#{id}
 	</if>
 	<if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
 		and last_name like #{lastName}
 	</if>
 </sql>

调用方法: include 标签当中的refid属性填写sql的id名,即可调用。

<select id="getEmpsByConditionIf" resultType="com.gzl.mybatis.bean.Employee">
 	select * from tbl_employee
 	<!-- where -->
 	<where>
 		<include refid="insertColumn"></include>
 	</where>
 </select>

include还可以自定义一些property

<include refid="insertColumn">
	<property name="testColomn" value="abc"/>
</include>

总结

总体来说Mybatis当中提供的这些标签有一些在实际开发当中还是会经常用到的,比如if、sql等
如果您还有什么疑问也可以评论在下方,或者私信都是可以的。

感觉小编整理的还可以的,确实您也学到了,麻烦帮小编点个关注或者点个赞,哈哈哈

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

(十三)Mybatis动态SQL各种标签的用法详解 的相关文章

  • 使用 objectGUID 进行查询 - Spring LDAP 模板

    我正在尝试获取 存储并依次使用 objectGUID 来查询 Active Directory 为了获取用户属性我正在使用以下 public static class MyDnKeyValueAttMapper implements Att
  • 在 MongoDB Java 驱动程序中如何使用 $filter

    我有一个适用于 MQL 的查询 我需要将其翻译成Java MQL 中的查询如下所示 db
  • java替代Thread.stop()来中断特定调用

    我正在寻找一种方法来告诉这个调用 大约需要 20 120 秒 final Area image final AffineTransform transform new AffineTransform transform scale imag
  • 按下按钮时清除编辑文本焦点并隐藏键盘

    我正在制作一个带有编辑文本和按钮的应用程序 当我在 edittext 中输入内容然后单击按钮时 我希望键盘和焦点在 edittext 上消失 但我似乎无法做到这一点 我在 XML 中插入了这两行代码 android focusable tr
  • 使用 xuggle 将 mp3 转换为 wav 出现异常

    我正在尝试将 mp3 转换为 wav 代码在这里 String mp3 F work pic2talk38512 mp3 String wav F work pic2talk38512 wav TranscodeAudioAndVideo
  • Eclipse 自动完成更改变量名称

    只是一个愚蠢的问题 但很难搜索 因为有很多关于 Eclipse 自动完成的主题 而且很难找到与我的问题匹配的内容 所以问题是 如果我写 MyClass MyVarName 然后按空格键 添加 new MyClass Eclipse 自动添加
  • 确定代码是否在 App Engine 运行时 (Java) 上运行

    如何确定某些代码 Serv let 或简单的类 是否正在 Google App Engine 运行时 Java 上运行 以便决定是否使用 App Engine 的特定库 是否有一些可靠的运行时环境 ID 您可以检查com google ap
  • 在java.util中获取错误ArrayList不带参数[重复]

    这个问题在这里已经有答案了 我已经创建了一个类 Student 现在我尝试将我的 Student 对象存储在 ArrayList 中 但在编译 ArrayList 不接受参数时出现错误 我已经检查了我的代码很多次 但找不到问题所在 我的学生
  • 在Java中使用BufferedWriter写入文件时监视文件大小?

    我正在将一个可能很长的项目列表写入文件 我正在写的项目的长度是可变的 如果生成的文件大小大于10M 则应将其分成多个文件 为了提高性能 我目前使用 BufferedWriter 如下所示 final FileOutputStream fos
  • 给定一个单词列表 - 在 java 中完成单词的好的算法是什么?权衡:速度/效率/内存占用

    我正在探索潜在的免费 付费应用程序的硬件 软件要求 最终目标是移动 Java 应用程序 该应用程序将从这个简单的目标开始 给定数据库中相关单词的列表 能够对单个字符串输入进行单词补全 换句话说 我已经知道数据库的内容 但算法的内存占用 速度
  • Java 7 中 Object 和 int 的比较

    最近我偶然发现了一个问题 让我停下来思考 对我来说 下面的代码应该总是会触发错误 但是当我的一位同事问我为什么 Eclipse 没有显示错误时 我无法回答任何问题 class A public static void main String
  • 如何告诉 cxf 将包装类型保留在方法中?

    在我的 WSDL 中我有一个操作
  • Akka 和 spring 配置

    我正在尝试将 akka 与 spring 结合起来 但没有成功 基本上 我的应用程序似乎不习惯读取 akka 模式 具有架构的 service context xml 的一部分
  • 多对多不检索映射数据

    Spring boot 2 5 6 我无法安装版本 概要文件 java Getter Setter NoArgsConstructor AllArgsConstructor EqualsAndHashCode FieldDefaults l
  • java Runtime.getRunTime().exec 和通配符?

    我正在尝试使用删除垃圾文件 Process p Runtime getRuntime exec 只要我不使用通配符 它 就可以正常工作 即 Process p Runtime getRuntime exec bin rm f specifi
  • java 1.8下无法启动eclipse

    java 1 8 升级后我无法启动 eclipse 附上错误截图 这是我的 eclipse 配置设置 我该如何解决 startup plugins org eclipse equinox launcher 1 3 0 v20120522 1
  • 链表中的虚拟节点

    问 什么时候使用它们 作业问题 列表中的第一个和最后一个节点 有时用作列表中的第一个和最后一个节点 从未用作列表中的第一个和最后一个节点 维基百科说 哨兵节点是与链接一起使用的专门指定的节点 列表和树作为遍历路径终止符 哨兵节点的作用是 不
  • Python 可以替代 Java 小程序吗?

    除了制作用于物理模拟 如抛射运动 重力等 的教育性 Java 小程序之外 还有其他选择吗 如果你想让它在浏览器中运行 你可以使用PyJamas http pyjs org 这是一个 Python 到 Javascript 的编译器和工具集
  • Drools:为什么是无状态会话?

    Drools 使用会话来存储运行时数据 为此 有两种会话 无状态和有状态 与无状态会话相比 有状态会话允许迭代调用 并且似乎比无状态会话具有所有优势 那么为什么会有无状态会话呢 他们服务的目的是什么 与有状态会话相比 它们的优势是什么 谢谢
  • JSP 和 scriptlet

    我知道现在使用 scriptlet 被认为是禁忌 没关系 我会同意Top Star的话 因为我目前只是Java新手 到目前为止我听到的是 它是为了让设计师的生活更轻松 但我想知道 这是否与JSP页面的性能有关 另一方面 如果只是为了 让设计

随机推荐

  • 源NAT,目的NAT和PAT以及端口映射的区别?

    一 NAT 1 动态NAT 地址复用 指将内部私有IP转换为公网IP地址时 IP的对应关系是不确定的 也就是说只要指定哪些内部地址可以进行NAT转换 以及哪些可以的合法的IP地址可以作为外部地址 就可以进行动态转换了 也可以使用多个合法地址
  • unity3d运行后自动暂停_Unity3D 关于延迟、暂停执行脚本的几个方法总结

    1 InvokeRepeating函数 和 Invoke函数 个人认为最为有效方法 用法 InvokeRepeating delayOpen 1 5 1秒后调用 delayOpen 函数 之后每5秒调用一次 写在Start函数内 Invok
  • python实现时间序列信号的频谱、倒频谱以及功率谱

    python实现时间序列信号的频谱 倒频谱以及功率谱 认识傅里叶变换 一 频谱 1 引入库 2 频谱函数封装 二 功率谱 功率谱谱函数封装 三 倒频谱 倒频谱谱函数封装 以振动信号为例 认识傅里叶变换 这里我就不多说了 百度谷歌一大堆说的明
  • /sys/module/ 模块信息 目录与/proc/modules文件

    在内核模块编译中 会选择编译成模块 或者build in 内核镜像中 其中对内核模块有很好的的说明 这也是linux在嵌入式当中得到广泛应用的充分体现 内核中有很多功能选项 其中有许多使我们不需要的 内核设计成模块的优势所在就在这里 不需要
  • Android java.lang.UnsatisfiedLinkError: No implementation found

    例如 该项目的如下报错 java lang UnsatisfiedLinkError No implementation found for void org webrtc PeerConnectionFactory nativeIniti
  • Python 环境变量配置详解

    文章目录 1 配置前准备 1 1 检查环境变量是否配置成功 1 2 查询 python exe 的安装路径 2 配置步骤 2 1 进入高级系统设置 2 2 设置环境变量 2 1 1 配置 Python exe 所在路径 2 2 1 配置 p
  • GIT 仓库 子模块 SUBMODULE 拉取子仓库代码

    找到 gitmodules 文件所在的目录 在该目录下运行命令 git submodule init git submodule update
  • DNS请求响应

    问题背景 在无线网络可用 而有线网络不可用的场景下 依靠第三方接口解析域名 或者udp tcp接口内部解析域名 会默认阻塞10秒钟 办法 自行定制dns请求及响应 BOOL SendDNSRequest sockaddr in sockAd
  • Low Memory Killer

    oom score adj 计算方法 oom score adj oom adj OOM SCORE ADJ MAX OOM DISABLE OOM SCORE ADJ MAX 1000 OOM DISABLE 17 其中 oom adj
  • c# mysql 二进制图片_C#将image中的显示的图片转换成二进制

    1 将Image图像文件存入到数据库中 我们知道数据库里的Image类型的数据是 二进制数据 因此必须将图像文件转换成字节数组才能存入数据库中 View Code 将本地图片转换成二进制保存起来 private byte SetImageT
  • MATLAB元胞数组

    MATLAB元胞数组 元胞数组 元胞数组是MATLAB的一种特殊数据类型 可以将元胞数组看做一种无所不包的通用矩阵 或者叫做广义矩阵 组成元胞数组的元素可以是任何一种数据类型的常数或者常量 每一个元素也可以具有不同的尺寸和内存占用空间 每一
  • 后缀表达式的计算【C语言】【数据结构】

    什么是后缀表达式 逆波兰表达式 百度百科 后缀表达式又称 逆波兰表达式 先看一下我们常见的 2 5 3 9 6 这其实就是中缀表达式 将其写成后缀表达式就是 2 5 3 9 6 每个字符用空格隔开 中缀表达式到后缀表达式怎么变的 为什么要这
  • uniapp获取手机网络状态和手机系统信息(如4g,wifi)

    先看代码 复制使用即可 uni内置方法uni getNetworkType用来获取网络状态 uni getSystemInfo用来获取手机系统
  • WM_COMMAND与消息的传递

    上面是一张MFC的类图局部 MFC将消息分为三大类 命令消息WM COMMAND 凡是由CCmdTarget派生的类 均可接收该消息 标准消息WM xxx 凡是由CWnd派生的类 均可接收该消息 控件通知消息WM NOTIFY WM COM
  • 【Vue报错】app.js:167 Uncaught TypeError: Cannot read properties of undefined (reading ‘install‘)

    背景 控制台报错 app js 167 Uncaught TypeError Cannot read properties of undefined reading install at Function Vue use vue runti
  • 播放PowerPoint(PPT)并嵌入窗体

    根据需求 需要在我们的应用程序中可以播放PPT并操作翻页 由于使用的是c builder 没有VS的Windows控件库 所以一开始的打算是把PPT当成一个整体窗口来处理 操作步骤 1 以播放方式打开PPT 通过Baidu发现是POWERP
  • 电脑xm音乐格式转mp3

    正常下载的喜马拉雅文件是一个 xm格式文件 无法通过正常的格式工厂等格式转换工具进行转换 因为 xm文件它本身就不是一个通用的 被广泛认可的音频文件 所以 不要在xm格式文件上下功夫了 这是一种无用功 有人就要骂娘了 什么 你所说的转码方式
  • MySQL修改密码的3种方式< MySQL忘记root密码后如何重置?

    1 使用 SET PASSWORD 命令 步骤 1 输入命令mysql u root p指定 root 用户登录 MySQL 输入后按回车键输入密码 如果没有配置环境变量 请在 MySQL 的 bin 目录下登录操作 步骤 2 使用 SET
  • oracle定义表注意事项,【TABLE】oracle表在线重定义注意事项

    下面是无法使用在线重定义的一些情况 点击 此处 折叠或打开 Tables with the following characteristics cannot be redefined online 9 0 1 Tables with no
  • (十三)Mybatis动态SQL各种标签的用法详解

    这篇文章主要讲述Mybatis动态SQL各种标签的用法详解 学习Mybatis动态sql看这一篇博客足够了 目录 什么是静态SQL 什么是动态SQL 动态SQL标签详解 IF标签的用法 where标签的用法 trim标签的用法 choose