动态SQL

动态查询

select * from cities where city="" and id>="",查询输入条件可能只有city和province中的一个

由于xml文件中不识别 大于、小于等符号,需要进行转义

原符号替换符号
< &lt;
<= &lt;=
> &gt;
>= &gt;=
& &amp;
' &apos;
" &quot;

映射文件

  • 查询传入的city不为空,查询该city

  • 查询传入的province不为空,查询 <=province

    <!--多条件查询[动态SQL],会自动组合成一个正常的where语句
     city和id会从map中自动获取-->
    <select id="findByCondition" parameterType="map" resultMap="citiesMap">
        select * from cities 
        <where>
            <if test="city!=null"> city=#{city} </if>
            <if test="id!=null"> and id&gt;=#{id} </if>
        </where>
    </select>

DAO层方法

动态修改

update cities set city="",province="" where id="",修改字段可能只有city和province中的一个

映射文件

    <!-- 动态更新,不要忘记更新多个字段时,字段间的逗号 -->
    <update id="updateByCondition" parameterType="map">
        UPDATE cities
        <set>
            <if test="city!=null"> city=#{city},</if>
            <if test="province!=null"> province=#{province}</if>
        </set>
        WHERE id=#{id};
    </update>

动态删除(批量删除)

delete from cities where id in (...),同时删除几条数据

映射文件

    <!--动态删除(批量删除)-->
    <delete id="deleteByCondition" parameterType="int">
    <!-- foreach用于迭代数组元素
         open表示开始符号
         close表示结束符合
         separator表示元素间的分隔符
         item表示迭代的数组,属性值可以任意,但提倡与方法的数组名相同
         #{ids}表示数组中的每个元素值
    -->
        delete from cities where id in
        <foreach collection="array" open="(" close=")" separator="," item="ids">
            #{ids}
        </foreach>
    </delete>

DAO层代码

public void deleteByCondition(int... ids){
        ...
    }

动态新增

insert into cities(id,city,province,country) values(?,?,?),新增数据的字段可能只有city和province中的一个,有两部分是不确定的,values会根据插入的字段而变化

SQL代码块是不能像之前那样帮我们自动去除多余的逗号的,因此我们需要使用 trim 标签来自己手动去除后缀

映射文件

    <!--SQL片段,有两个SQL片段:key和value-->
    <sql id="key">
        <trim suffixOverrides=",">
            <if test="city!=null">city,</if>
            <if test="province!=null">province</if>
        </trim>
    </sql>
    <sql id="value">
        <trim suffixOverrides=",">
            <if test="city!=null">#{city},</if>
            <if test="province!=null">#{province}</if>
        </trim>
    </sql><insert id="insertByCondition" parameterType="mybatis_test.Cities">
        INSERT INTO cities(id,<include refid="key"/>,country) values(#{id},<include refid="value"/>,#{country})
    </insert>

动态SQL的标签

参考  https://mybatis.org/mybatis-3/zh/dynamic-sql.html

if

    <select id="findByCondition" parameterType="map" resultMap="citiesMap">
        SELECT * FROM cities WHERE city=#{city}
            <if test="province!=null"> AND id&lt;=#{id} </if>
        </where>
    </select>

如果不传入id,则根据传入的city查询;如果传入id,根据city和id查询

choose(<when>、<otherwise>)

    <select id="findByCondition" parameterType="map" resultMap="citiesMap">
        SELECT * FROM cities
        <choose>
            <when test="city!=null">city=#{city}</when>
            <when test="province!=null">AND province=#{province}</when>
            <otherwise>AND id=#{id}</otherwise>
        </choose>
    </select>

类似Java的switch语句

如果传入了city就按city查询,传入了province就按province查询,两个都没有,就按id查询

where、set、trim

  • where

    <select id="findByCondition" parameterType="map" resultMap="citiesMap">
        SELECT * FROM cities
        <where>
            <if test="city!=null">AND city=#{city} </if>
            <if test="province!=null"> AND id&lt;=#{id} </if>
        </where>
    </select>

where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除

  • set

    <update id="updateByCondition" parameterType="map">
        UPDATE cities
        <set>
            <if test="city!=null"> city=#{city},</if>
            <if test="province!=null"> province=#{province}</if>
        </set>
        WHERE id=#{id};
    </update>

set 元素可以用于动态包含需要更新的列,忽略其它不更新的列

  • trim

一般用于sql语句中去除或添加 前缀、后缀,如去除and关键字逗号 ,给sql语句前添加“where““set““values“ ,可用于选择性插入、更新、删除或者条件查询等操作

属性:

  • prefix:给sql语句拼接的前缀

  • suffix:给sql语句拼接的后缀

  • prefixOverrides:去除sql语句前面的关键字或者字符,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND"

  • suffixOverrides:去除sql语句后面的关键字或者字符

如使用trim完成where的功能,去除前缀 "AND"

<trim prefix="WHERE" prefixOverrides="AND">
    <if test="state != null">
      state = #{state}
    </if> 
    <if test="title != null">
      AND title like #{title}
    </if>
</trim>

使用trim去除SQL片段的后缀

    <sql id="key">
        <trim suffixOverrides=",">
            <if test="city!=null">city,</if>
            <if test="province!=null">province</if>
        </trim>
    </sql>

foreach

    <delete id="deleteByCondition" parameterType="int">
        delete from cities where id in
        <foreach collection="array" open="(" close=")" separator="," item="ids" index="index">
            #{ids}
        </foreach>
    </delete>

open 表示开始符号,close 表示结束符号,separator 表示元素间的分隔符,item 表示迭代的数组,属性值可以任意,但提倡与方法的数组名相同 ,#{ids}表示数组中的每个元素值

指定一个集合,声明可以在元素体内使用的集合项(ids)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。

可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,ids 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,ids 是值。

bind

bind标签中,value对应传入实体类的某个字段,city属性既给对应字段取的变量名。在value属性中可以使用字符串拼接等特殊处理,用作 like 模糊查询。

<bind city="xxx" value="'%'+ id + '%'"/>

 

posted @ 2020-10-28 21:31  hjy1995  阅读(114)  评论(0编辑  收藏  举报