zoukankan      html  css  js  c++  java
  • mybatis中实现动态SQL

         动态SQL语句,也就意味着SQL语句不在是一成不变的而是具有多样性.

    if

      if的用法还是跟平常差不多的(不过没有else if也没有else)

    <update id="modify" parameterType="User">
            UPDATE `smbms_user`
            <trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
                <if test="userCode!=null">`userCode` = #{userCode} , </if>
                <if test="userName!=null">`userName` = #{userName} , </if>
                <if test="userPassword!=null">`userPassword` = #{userPassword} , </if>
                <if test="gender!=null">`gender` = #{gender} , </if>
                <if test="birthday!=null">`birthday` = #{birthday} ,</if>
                <if test="phone!=null">`phone` = #{phone} , </if>
                <if test="address!=null">`address` = #{address} , </if>
                <if test="userRole!=null">`userRole` = #{userRole} , </if>
                <if test="createdBy!=null">`createdBy` = #{createdBy} , </if>
                <if test="creationDate!=null">`creationDate` = #{creationDate} , </if>
                <if test="modifyBy!=null">`modifyBy` = #{modifyBy}</if>
            </trim>
        </update> 

    如上面的代码,如果是空的字段则不执行更新操作

    choose(when,otherwise)

      choose就相当于Java中的switch,when相当于case,otherwise相当于default

    <select id="getBill" resultType="Bill">
            SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
            WHERE 1=1
            <choose>
                <!-- 条件为false则继续执行下面的when,反之亦然如此 -->
                <when test="id!=null">
                    AND    b.providerId=#{id} 
                </when>
                <!-- 条件为true则不会执行otherwise,反之亦然如此 -->
                <when test="proName!=null">
                    AND p.proName LIKE CONCAT('%',#{proName},'%')
                </when>
                <!-- 当都不满足时执行默认值 -->
                <otherwise>
                    AND p.proContact LIKE CONCAT('%张%')
                </otherwise>
            </choose>
        </select>

    where

    此标签可以忽略条件中多余的and和or如下

    SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
            <where>
                <if test="id!=null">
                     AND b.providerId=#{id}
                </if>
                <if test="proName!=null">
                     AND p.proName LIKE CONCAT('%',#{proName},'%')
                </if>
            </where>

    假设id为1 proName为北京 两个if都满足条件时就会拼凑成这样

    SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id WHERE b.providerId=1 AND p.proName LIKE CONCAT('%北京%')

    其实解决这种情况不用where也是可以的,只需在前面加上一个为真的条件即可

    SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
            where 1=1
            <if test="id!=null">
                 AND b.providerId=#{id}
            </if>
            <if test="proName!=null">
                 AND p.proName LIKE CONCAT('%',#{proName},'%')
            </if>

    效果也是一样的

    set

    此标签可以忽略多余的逗号

    UPDATE `smbms_user` 
            <set>
                <if test="userPassword!=null">
                    `userPassword` = #{userPassword},
                </if>
            </set>
               WHERE `id` = #{id} ;

    trim

    此标签属性如下

    1. prefix:通过自动识别是否有返回值,在trim包含的内容上加上前缀
    2. suffix:在trim包含的内容上加上后缀
    3. prefixoverrides:对trim包含内容的首部进行指定内容的忽略
    4. suffixoverrides;对于trim包含内容的尾部进行指定内容的忽略

    栗子1

    <!-- 添加内容前面加上 where 并且忽略 and或者or -->
            <trim prefix="where" prefixOverrides="and|or">
                <if test="userRole!=null">
                    and userRole=#{userRole}
                </if> 
                <if test="userName!=null and userName!=''">
                    and u.userName like CONCAT('%',#{userName},'%')
                </if>
                order by creationDate DESC limit #(from),#(pageSize)
            </trim>

    栗子2

    UPDATE `smbms_user`
            <!-- 在内容前加上 set 并且忽略内容最后的逗号 且在内容后面加上查询条件  -->
            <trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
                <if test="userCode!=null">`userCode` = #{userCode} , </if>
                <if test="userName!=null">`userName` = #{userName} , </if>
            </trim>

    foreach

    此标签的属性如下

    1. item表示集合中每一个元素进行迭代时的别名
    2. index:指定一个名字,用于表示每次迭代的位置.好比for循环中自定义的 i
    3. open表示该语句以什么开始,在in条件语句中以"("开始
    4. separator表示在每次进行迭代之间以什么符号作为分隔 符,在in条件语句中以逗号进行分隔
    5. close表示以什么结束。在in条件语句中以")"结尾
    6. 在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,主要有以下3种情况:
      1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
      2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
      3. 如果传入的参数是多个的时候,我们一般把它们封装成一个Map了,此时属性值为map其中的一个key

    栗子1

    当入参为list时

    <select id="getUSerByRoleId_foreach_list" resultMap="userMapByRole">
            select * from smbms_user where userRole in
            <!-- 因为此处用了in,因此以 "("开头  ,")"结尾 ,","分隔 -->
            <foreach collection="list" item="roleList" open="(" separator="," close=")">
                #{roleList}
            </foreach>
        </select>

    栗子2

    当入参为数组时

    <select id="getUserByRoleId_foreach_array" resultMap="userMapByRole">
            select * from smbms_user where userRole in
            <!-- 因为此处用了in,因此以 "("开头  ,")"结尾 ,用","分隔 -->
            <foreach collection="array" item="roleIds" open="(" separator="," close=")">
                #{roleIds}
            </foreach>
        </select>

    栗子3

    当为map时

    <select id="getProvider"  resultMap="providerresult">
            SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
            where b.providerId in
            <!-- 因为此处用了in,因此以 "("开头  ,")"结尾 ,","分隔 此时的collection的值是map其中的一个key-->
            <foreach collection="#{bibli}" item="pros" open="(" separator="," close=")">
                <!-- 获取对象当中的属性 -->
                #{pros.providerId}    
            </foreach>
        </select>

    小结

    • if+set:动态完成更新操作
    • if+where:动态完成多条件查询
    • if+trim:完成多条件查询(代替where)或者更新操作(代替set)
    • choose(when,otherwise):动态完成多条件查询(多选一)
    • foreach:主要用于in条件查询中,迭代集合,最关键的部分为collection属性,根据不同的入参类型,该属性值则不同
      1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
      2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
      3. 如果传入的参数是多个的时候,我们一般把它们封装成一个Map了,此时属性值为map其中的一个key
  • 相关阅读:
    257. Binary Tree Paths
    324. Wiggle Sort II
    315. Count of Smaller Numbers After Self
    350. Intersection of Two Arrays II
    295. Find Median from Data Stream
    289. Game of Life
    287. Find the Duplicate Number
    279. Perfect Squares
    384. Shuffle an Array
    E
  • 原文地址:https://www.cnblogs.com/hfx123/p/9623363.html
Copyright © 2011-2022 走看看