美文网首页
MyBatis中使用SQL动态绑定

MyBatis中使用SQL动态绑定

作者: 小安的大情调 | 来源:发表于2018-11-23 23:25 被阅读0次

    如未作特殊说明,本文均为原创,转载请注明出处。

    [TOC]

    前言
    同在在编写业务代码时,会经常遇到多条件查询语句。在普通SQL中使用多条件查询有一个投机取巧的方法就是在条件语句前面加上where 1 = 1恒成立的条件,这样就不用考虑第一个条件是否成立,where or and的使用顺序。

    ​ 但是使用where 1 = 1这种恒成立的语句,会主动放弃MySQL索引查询,如果数据库非常庞大,那会是一场灾难。

    Mybatis中的动态绑定

    准备:


    标签表.png

    SQL语句的实现条件选择。

    if/choose/where/set

    1. IF:用if实现条件的选择,用于定义where的条件。
    2. choose:相当于java中的switch语句,通常whenotherwise一起使用。
    3. where:简化SQL语句中的where条件。
    4. set:解决SQL中更新语句。

    下面简单的说明下这几种关键字的用法。

    根据条件更新

        <update id="updateByPrimaryKeySelective" parameterType="com.tensquare.model.Label">
            update tb_label
            <set>
                <if test="labelname != null">
                    labelname = #{labelname,jdbcType=VARCHAR},
                </if>
                <if test="state != null">
                    state = #{state,jdbcType=VARCHAR},
                </if>
                <if test="count != null">
                    count = #{count,jdbcType=BIGINT},
                </if>
                <if test="recommend != null">
                    recommend = #{recommend,jdbcType=VARCHAR},
                </if>
                <if test="fans != null">
                    fans = #{fans,jdbcType=BIGINT},
                </if>
            </set>
            where id = #{id,jdbcType=VARCHAR}
        </update>
    

    choose:

        <select id="ChooseTest" resultMap="BaseResultMap" parameterType="com.tensquare.model.Label">
            SELECT * FROM tb_label
            WHERE 1=1
            <choose>
                <when test="id != null">
                    AND id = #{id}
                </when>
                <when test="labelname != null">
                    and labelname = #{labelname}
                </when>
                <otherwise>
                    and count = #{count}
                </otherwise>
            </choose>
        </select>
    

    这里使用了where 1 = 1来避免where 不知道哪一个判断正确的情况下。chooseJAVA中的swith类似,当遇到一个判断成立后,不会执行下面的。所以一般在使用动态sql查询时都使用<where></where>来自动提供在一个成立的条件前面不会添加and

    SQL多条件查询中的like使用和## 、#`的区别

    ​ 在mybatis中使用模糊查询时,可以使用以下三种方式:

    1. 直接拼接。(占位符/字符拼接)

      select * from tb_label where labelname like "%"#{labelname}"%"
      
      或者
      
      select * from tb_label where labelname like '%${labelname}%'
      
    2. 使用concat(str1,str2)函数将两个两个参数连接起来

      select * from tb_label where labelname like concat("%",concat(#{labelname},"%"))
      
    3. 将参数使用bind标签绑定在一起(这里书写一个完整的多条件动态查询,在mybatis中)

       <select id="findBySearch" resultMap="BaseResultMap" parameterType="com.tensquare.model.Label">
              SELECT
              <include refid="Base_Column_List"/>
              FROM tb_label
              <where>
                  <if test="id != null">
                      and id = #{id,jdbcType=VARCHAR}
                  </if>
                  <if test="labelname != null">
                        <bind name="newlabelname" value="'%'+labelname+'%'"/>
                        and labelname like #{newlabelname}
                  </if>
                  <if test="state != null">
                      and state = #{state}
                  </if>
                  <if test="count != null">
                      and count = #{count}
                  </if>
                  <if test="recommend != null">
                      and recommend = #{recommend}
                  </if>
              </where>
          </select>
      
    4. #$的区别

    在上面的第一种直接拼接的sql语句中可以看出,书写的方式不同,#有一种调用方法的感觉而$更像一种字符的拼接。

    ​ 这里可以指出#{}是一个占位符。而$则属于字符拼接。在安全方面来说,$相对来说比较容易被乘虚而入(SQL注入)。利于在判断语句中黑客添加依据判断作为拼接(labelname or 1=1)这样一来判断一定成立,数据就容易被窃取。

    ​ 在编译时,mybatis在控制台打印的sql语句不一样。

    #

    # 控制台打印sql.png
    $: $ sql拼接 控制台sql语句.png
    1. 在mybatis sql拼接时出现下列错误:


      sql语句中?号与参数个数不符.png

      sql语句中出现的占位符(?)的个数与参数不符合。

    总结

    ​ 加油!!!

    相关文章

      网友评论

          本文标题:MyBatis中使用SQL动态绑定

          本文链接:https://www.haomeiwen.com/subject/jszsqqtx.html