zoukankan      html  css  js  c++  java
  • 【mybatis】04-动态SQL

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

    通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句

    一、if:根据条件作为 where 子句的一部分
    如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 BLOG 都会返回;
    如果传入了 “title” 参数,那么就会对 “title” 一列进行模糊查找并返回对应的 BLOG 结果
    <select id="findActiveBlogWithTitleLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null"> AND title like #{title} </if> </select>

    二、choose、when、otherwise:我们不想使用所有的条件,而只是想从多个条件中选择一个使用。类似switch功能

    传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。若两者都没有传入,就返回标记为 featured 的 BLOG
    <select id="findActiveBlogLike"
         resultType="Blog">
      SELECT * FROM BLOG WHERE state = ‘ACTIVE’
      <choose>
        <when test="title != null">
          AND title like #{title}
        </when>
        <when test="author != null and author.name != null">
          AND author_name like #{author.name}
        </when>
        <otherwise>
          AND featured = 1
        </otherwise>
      </choose>
    </select>

    三、trim、where、set:

    存在的问题:如果没有匹配条件或匹配第2个if( where and title like 此时存在语法问题)
    <select id="findActiveBlogLike"
         resultType="Blog">
      SELECT * FROM BLOG
      WHERE
      <if test="state != null">
        state = #{state}
      </if>
      <if test="title != null">
        AND title like #{title}
      </if>
      <if test="author != null and author.name != null">
        AND author_name like #{author.name}
      </if>
    </select>

    解决方案:where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

    <select id="findActiveBlogLike"
         resultType="Blog">
      SELECT * FROM BLOG
      <where>
        <if test="state != null">
             state = #{state}
        </if>
        <if test="title != null">
            AND title like #{title}
        </if>
        <if test="author != null and author.name != null">
            AND author_name like #{author.name}
        </if>
      </where>
    </select>

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

    <trim prefix="WHERE" prefixOverrides="AND |OR ">
      ...
    </trim>

    样例:

    <insert id="saveCatalogInfo" parameterType="com.model.ApiInfo">
      INSERT INTO <include refid="tableName_Catalog" />
    <trim prefix="(" suffix=")" suffixOverrides=",">
      id,
      <if test="name != null">apiName,</if>
      <if test="typicalScenarios != null">typicalScenarios,</if>
      <if test="interfaceFunction != null">interfaceFunction,</if>
      <if test="interfaceConstraint != null">interfaceConstraint,</if>
      <if test="requestExamples != null">requestExamples,</if>
      <if test="responseExamples != null">responseExamples,</if>
      <if test="tenant != null">tenant,</if>
      <if test="createTime != null">createTime,</if>
      <if test="updateTime != null">updateTime,</if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      #{catalogId,jdbcType=VARCHAR},
      <if test="name != null">#{name,jdbcType=VARCHAR},</if>
      <if test="typicalScenarios != null">#{typicalScenarios,jdbcType=VARCHAR},</if>
      <if test="interfaceFunction != null">#{interfaceFunction,jdbcType=VARCHAR},</if>
      <if test="interfaceConstraint != null">#{interfaceConstraint,jdbcType=VARCHAR},</if>
      <if test="requestExamples != null">#{requestExamples,jdbcType=BLOB},</if>
      <if test="responseExamples != null">#{responseExamples,jdbcType=BLOB},</if>
      <if test="tenant != null">#{tenant,jdbcType=VARCHAR},</if>
      <if test="createTime != null">#{createTime,jdbcType=VARCHAR},</if>
      <if test="updateTime != null">#{updateTime,jdbcType=VARCHAR},</if>
    </trim>
    </insert>

     

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

    <update id="updateAuthorIfNecessary">
      update Author
        <set>
          <if test="username != null">username=#{username},</if>
          <if test="password != null">password=#{password},</if>
          <if test="email != null">email=#{email},</if>
          <if test="bio != null">bio=#{bio}</if>
        </set>
      where id=#{id}
    </update>

    四、foreach

    对集合进行遍历(尤其是在构建 IN 条件语句的时候)

    你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach

    • 当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。
    • 当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
    <select id="selectPostIn" resultType="domain.blog.Post">
      SELECT *
      FROM POST P
      WHERE ID in
      <foreach item="item" index="index" collection="list"
          open="(" separator="," close=")">
            #{item}
      </foreach>
    </select>
  • 相关阅读:
    【BZOJ 4151 The Cave】
    【POJ 3080 Blue Jeans】
    【ZBH选讲·树变环】
    【ZBH选讲·拍照】
    【ZBH选讲·模数和】
    【CF Edu 28 C. Four Segments】
    【CF Edu 28 A. Curriculum Vitae】
    【CF Edu 28 B. Math Show】
    【CF Round 439 E. The Untended Antiquity】
    【CF Round 439 C. The Intriguing Obsession】
  • 原文地址:https://www.cnblogs.com/clarino/p/14787142.html
Copyright © 2011-2022 走看看