八、动态SQL


Mybatis框架的 动态SQL 技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决 拼接SQL语句字符串时的痛点问题。

1、if(and/or)

if标签可通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之标签中 的内容不会执行

<select id="getStudentByCondition" parameterType="Map" resultType="Student">
    SELECT s_id id,s_name name,address,age FROM student WHERE 1=1
    <if test="name!='' and name!=null">
          AND name=#{name}
    </if>
    <if test="address!='' and address!=null">
          AND address=#{address}
    </if>
</select>

2、where

参考上例,where后面跟了个 1=1,是为了防止where 后面直接接and导致生成错误sql,用 <where>标签完美解决

where和 if一般结合使用,where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除(and/or)去掉

注意:where标签不能去掉条件最后多余的and或or

<select id="getStudentByCondition" parameterType="Map" resultType="Student">
    SELECT s_id id,s_name name,address,age FROM student
    <where>
        <if test="name!='' and name!=null">
              AND name=#{name}
        </if>
        <if test="address!='' and address!=null">
              AND address=#{address}
        </if>
    </where>
</select>

3、trim

如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。

trim用于去掉或添加标签中的内容;常用属性如下:

prefix:在trim标签中的内容的前面添加某些内容

prefixOverrides:在trim标签中的内容的前面去掉某个内容或通过管道符分隔的文本序列

suffix:在trim标签中的内容的后面添加某些内容

suffixOverrides:在trim标签中的内容的后面去掉某个内容或通过管道符分隔的文本序列

<!--如果我们把连接符写在后面...-->
<select id="getStudentByCondition" parameterType="Map" resultType="Student">
    SELECT s_id id,s_name name,address,age FROM student
    <trim prefix="where" prefixOverrides="and|or">
        <if test="name!='' and name!=null">
              name=#{name} AND
        </if>
        <if test="address!='' and address!=null">
              address=#{address} AND
        </if>
    </trim>
</select>

4、set

用于动态更新语句的类似解决方案叫做 setset 元素可以用于动态包含需要更新的列,忽略其它不更新的列。

<update id="updateById" parameterType="hom.wang.mybatis.model.User">
    update user
    <set>
        <if test="userName != null and userName != ''">
            user_name=#{userName},
        </if>
        <if test="age != null and age != ''">
            age=#{age},
        </if>
        <if test="sex != null and sex != ''">
            sex=#{sex},
        </if>
        <if test="phone != null and phone != ''">
            phone=#{phone},
        </if>
        <if test="email != null and email != ''">
            email=#{email},
        </if>
    </set>
    where user_id=#{userId}
</update>

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。与 set 元素等价的自定义 trim 元素如下:

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

注意,我们覆盖了后缀值设置,并且自定义了前缀值。

5、choose、when、otherwise

类似 if..else if...elseswitch 语句

<select id="getStudentByCondition" parameterType="List" resultType="Student">
    SELECT s_id id,s_name name,address,age FROM student 
    <where>
        <choose>
            <when test="name!=''">
                  s_name like #{name}
            </when>
            <when test="address!=''">
                  address like #{address}
            </when>
            <otherwise>
                  1=0
            </otherwise>
        </choose>
    </where>
</select>

6、foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。

属性:

collection:设置要循环的数组或集合(建议使用@Param指定)
index:当前迭代的序号
item:本次迭代获取到的元素
open:开始
close:结束
separator:分隔符

<!--int deleteByArray(Integer[] ids)
	如果不用@Param指定参数名,数组的话默认参数map是[arry, arg0],集合就是[collection, list, arg0]
-->
<delete id="deleteByArray">
    delete from goods where 
    <foreach collection="array" item="id" open=" id in (" close=")" separator=",">
          #{id} 
    </foreach> 
</delete>

<!--批量添加
	int insertSome(List<User> users)
-->
<insert id="insertSome">
    insert into user values
    <foreach collection="list" item="user" separator=",">
    	(null, #{user.userName}, #{user.age}, #{user.sex}, #{user.phone}, #{user.email})
    </foreach>
</insert>

7、sql

sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入。

<sql id="BaseSql">
    user_id, user_name, age, sex, phone, email
</sql>

<select id="selectAll" resultMap="BaseResultMap">
    select <include refid="BaseSql"/>
    from user
</select>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纯纯的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值