学习Mybatis动态SQL Day3

本文介绍了MyBatis框架中的动态SQL特性,包括if、where/if、set、choose、foreach和trim标签的用法,强调了其在灵活性和性能上的优势,同时也提到了动态SQL在安全方面的潜在风险——SQL注入问题。
摘要由CSDN通过智能技术生成

一:MyBatis动态 sql 是?

  1. 动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它类似的框架中,开发人员通常需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询。
  2. 动态SQL:code that is executed dynamically。 它一般是根据用户输入或外部条件动态组合的SQL语句块。 动态SQL能灵活的发挥SQL强大的功能、方便的解决一些其它方法难以解决的问题。 相信使用过动态SQL的人都能体会到它带来的便利,然而动态SQL有时候在执行性能 (效率)上面不如静态SQL,而且使用不恰当,往往会在安全方面存在隐患 (SQL 注入式攻击)。

二、Mybatis 动态 sql 是做什么的?

Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。

三、动态SQL的常用标签

四、MyBatis标签

1.if标签:条件判断

if标签是MyBatis框架动态SQL技术中重要且常用的标签之一,它所实现的功能与Java中的if语句基本相同,用法也很相似。
<if  test = "条件判断,返回true或false" >
	SQL语句
</if>
<select id="getUserList" parameterType="map" resultType="User">
  SELECT * FROM users
  WHERE 1=1
  <if test="name != null">
    AND name = #{name}
  </if>
  <if test="age != null">
    AND age = #{age}
  </if>
</select>
在上述中,我们定义了一个名为getUserList的查询语句。使用了<if>标签来根据传入的参数进行条件判断,根据条件动态地生成SQL语句。
  • <if test="name != null">表示如果传入的name参数不为空,则会在SQL语句中添加AND name = #{name}这个条件;
  • <if test="age != null">表示如果传入的age参数不为空,则会在SQL语句中添加AND age = #{age}这个条件;
这样,在运行时,根据传入的参数是否为空,动态地生成相应的SQL语句,实现了灵活的条件查询。

2.where+if标签

where、if同时使用可以进行查询、模糊查询
<where>
	<if test="条件判断">
		SQL语句
	</if>
	…
</where>
<select id="getUserList" parameterType="map" resultType="User">
  SELECT * FROM users
  <where>
    <if test="name != null and name != ''">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </where>
</select>
在上述中,我们定义了一个名为getUserList的查询语句。使用了<where>标签包裹起来,在其中使用了<if>标签进行条件判断。
  • <if test="name != null and name != ''">表示如果传入的name参数不为空且不为空字符串,则会在WHERE子句中添加AND name = #{name}这个条件;
  • <if test="age != null">表示如果传入的age参数不为空,则会在WHERE子句中添加AND age = #{age}这个条件;
注意,<where>标签会自动处理条件之间的关系,并根据条件是否成立来消除多余的ANDOR连接词,使生成的SQL语句更加符合预期。
这样,在运行时,根据传入的参数是否满足条件,动态地生成相应的WHERE子句,实现了灵活的条件查询。

 3.set+if标签

set可以用来修改
<set>
	<if test="条件判断">
		SQL语句
	</if>
	…
</set>
<update id="updateUser" parameterType="User">
  UPDATE users
  <set>
    <if test="name != null and name != ''">
      name = #{name},
    </if>
    <if test="age != null">
      age = #{age},
    </if>
    <if test="email != null and email != ''">
      email = #{email},
    </if>
  </set>
  WHERE id = #{id}
</update>
在上述中,我们定义了一个名为updateUser的更新语句。使用了<set>标签包裹起来,在其中使用了多个<if>标签进行条件判断。
  • 每个<if>标签表示一个字段的更新条件。例如,<if test="name != null and name != ''">表示如果传入的name参数不为空且不为空字符串,则会在SET子句中添加name = #{name},这个条件;
  • 每个字段的更新条件以逗号结尾,最后一个更新条件不需要加逗号。
注意,<set>标签会自动处理条件之间的逗号和空格,使生成的SET子句更加符合预期。
这样,在运行时,根据传入的参数是否满足条件,动态地生成相应的SET子句,实现了灵活的字段更新。

 4.choose(when,otherwise) 语句

choose是一个组合标签,通常与when、otherwise标签配合使用 类似于Java中switch语句
<choose>
	<when test="条件判断,返回true或false">
	</when>
	<when test="条件判断,返回true或false">
	</when>
	...
	<otherwise>
	</otherwise>
</choose>
<select id="getUserList" parameterType="map" resultType="User">
  SELECT * FROM users
  WHERE 1=1
  <choose>
    <when test="name != null">
      AND name = #{name}
    </when>
    <when test="age != null">
      AND age = #{age}
    </when>
    <otherwise>
      AND status = 1
    </otherwise>
  </choose>
</select>
在上述中,我们定义了一个名为getUserList的查询语句。使用了<choose>标签包裹起来,在其中使用了多个<when>标签和一个<otherwise>标签。
  • <when>标签表示一个条件分支,类似于Java中的case语句。例如,<when test="name != null and name != ''">表示如果传入的name参数不为空且不为空字符串,则会在SQL语句中添加AND name = #{name}这个条件;
  • <otherwise>标签表示默认分支,类似于Java中的default语句。在上述示例中,如果前面的<when>条件都不满足,则会在SQL语句中添加AND status = 1这个条件。
这样,在运行时,根据传入的参数判断条件,动态地选择生成相应的查询条件,实现了灵活的查询逻辑。

5.foreach标签

迭代一个集合,通常用于in条件

<select id="getUserList" parameterType="map" resultType="User">
  SELECT * FROM users
  WHERE id IN
  <foreach item="item" index="index" collection="idList" open="(" separator="," close=")">
    #{item}
  </foreach>
</select>
这样,在运行时,会根据传入的idList参数生成一个包含多个ID值的查询条件,例如:WHERE id IN (1, 2, 3)
需要注意的是,<foreach>标签中的collection属性可以是任何实现了java.util.Collection接口的集合类型,如ListSet等。

6.trim

trim标记是一个格式化的标记,可以完成set或者是where标记的功能
<trim prefix = "前缀" 
	  suffix = "后缀" 
	  prefixOverrides = "忽略前缀" 
	  suffixOverrides = "忽略后缀" >
	…
</trim>

prefix="WHERE"表示在修剪后的SQL语句前添加的前缀,这里是WHERE关键字;
prefixOverrides="AND |OR "表示需要从修剪后的SQL语句中移除的前缀字符串,这里是AND和OR连接词;


<select id="getUserList" parameterType="map" resultType="User">
  SELECT * FROM users
  <trim prefix="WHERE" prefixOverrides="AND |OR ">
    <if test="name != null and name != ''">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </trim>
</select>
这样,在运行时,根据传入的参数是否满足条件,动态地生成相应的查询条件,并通过<trim>标签处理掉可能产生的多余字符。
你可以根据实际需求调整prefixprefixOverrides属性的值,以及在<trim>标签内编写适合的条件判断表达式。
注意,如果使用<trim>标签处理SET子句中的多余字符,可以使用suffixOverrides属性。

总结:

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值