0
点赞
收藏
分享

微信扫一扫

Mybatis的特性详解——动态SQL

君心浅语 2022-09-08 阅读 167

Mybatis的特性详解——动态SQL


前言

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

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


一、动态sql的元素

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

1.MyBatis if标签:条件判断

<if test="判断条件">
    SQL语句
</if>
<select id="selectAllBaseData" resultMap="myResult">
    select id,name from baseData
    <if test="name != null">
        where name like #{name}
    </if>
</select>
<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标签

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

示例

<mapper namespace="net.biancheng.mapper.WebsiteMapper">
    <select id="selectWebsite">
        SELECT id,name,url,age,country
        FROM 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>

3.MyBatis where标签

where 标签

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

示例

<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标签

    <!--使用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标签

<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。

示例

  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标签

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

bind 元素属性如下:

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

示例

//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,country
    FROM User
    WHERE name like #{pattern_name}
    AND url like #{pattern_url}
</select>

7.MyBatis trim标签

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

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

<select id="selectUser" resultType="User">
    SELECT id,name,url,age,country
    FROM 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>

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

举报

相关推荐

0 条评论