• 最常用的动态sql语句梳理Mybatis(转)


      公司项目中一直使用Mybatis作为持久层框架,自然,动态sql写得也比较多了,最常见的莫过于在查询语句中使用if标签来动态地改变过滤条件了。Mybatis的强大特性之一便是它的动态sql,免除了拼接sql带来的各种麻烦,在开发项目的过程中,常见的和不常见的你都有可能会用到,现在就来把这一块总结一下。

    •   if
    •   choose(when,otherwise)
    •   trim(where,set)
    •   foreach

    if

    复制代码
    <select id="getCategory" parameterType="EshopShopCategory" resultMap="EshopCategory" >
       SELECT * from MALLT_SHOP_CATEGORY t WHERE (1=1)
        <if test="eshopShopCategory.shopCategoryId!=null">
            AND t.shop_category_id  =#{eshopShopCategory.shopCategoryId}
        </if>
        <if test="eshopShopCategory.shopCategoryName!=null">
            AND t.SHOP_CATEGORY_NAME  like '%${eshopShopCategory.shopCategoryName}%'
        </if>
        <if test="eshopShopCategory.shopId==null">
            AND t.shop_id=0 
        </if>
        ORDER BY SEQUENCE_NO
    </select>
    复制代码

      这通常用于多条件组合查询。

    复制代码
    <insert id="addProductCategory" parameterType="EshopShopCategory">
            insert into  MALLT_SHOP_CATEGORY(
            <if test="shopCategoryName!=null and shopCategoryName!='' ">
              shop_category_name,
            </if>
            <if test="shopId!=null and shopId!=''">
                shop_id,
            </if>
            ADD_TIME) 
            values(
              <if test="shopCategoryName!=null and shopCategoryName!=''">
                  #{shopCategoryName,jdbcType=VARCHAR},
              </if>
              <if test="shopId!=null and shopId!=''">
                  #{shopId,jdbcType=NUMERIC},
              </if>
              current_timestamp
           )     </insert> 
    复制代码
    这适用于数据库有默认值的时候可以不让插入空值。
    复制代码
    <update id="updateProductCategory" parameterType="EshopShopCategory" >
          update MALLT_SHOP_CATEGORY t set 
          <if test="shopCategoryName!=null">
              t.shop_category_name=#{shopCategoryName,jdbcType=VARCHAR},
          </if>
          <if test="updateUser!=null">
              t.update_user=#{updateUser,jdbcType=VARCHAR} ,
          </if>
          t.update_time=current_timestamp
          where t.shop_category_id=#{shopCategoryId,jdbcType=NUMERIC}
    </update>
    复制代码

    这条动态地修改语句用得非常多,是因为很多时候我们在做修改操作时并不确定到底要修改哪些字段(哪些属性),可能有的需要保存原值不变,这时候就可以做动态的sql,你新建一个对象后将需要修改的字段附上新值,这样不用修改的属性在这个对象上表现地是null,调用这个动态的sql时便可以完成部分修改。

    choose,when,otherwise

          适用场景:我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。(我感觉它有点像提供多种条件规则时,而这些规则又可以综合写在一起时)

    复制代码
    <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>
    复制代码

    到目前为止,我还没有用到过choose,以后多留意。

    trim,where,set

    为了避免当if动态条件都不成立时,或者第一个条件不成立第二个条件成立时出现诸如"select * from TableA where"或者"select * from TableA and where"病态sql,我们可以使用trim,where,set标签来解决。

    复制代码
    <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>
    复制代码

    在实际应用中,我通常是不写where标签,而在where关键字之后加上1=1的条件。即不管有无动态条件,总可以得到完整的sql:select * from A where 1=1。。。

    复制代码
    <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

    foreach有时候在项目中会遇到,而且不止一次,用的时候是需要动点脑子的。通常用于筛选出在多个值组成的一个集合中或者排除多个值的场景,说白了,也就是我们之前写sql时用到in、not in的时候:(集合是动态不确定的,需要从前台传值过来)

    复制代码
    <select id="selectNumInOrder" resultType="String">
         select count(0) from eshop_order a left join eshop_order_item b on a.ORDER_ID = b.ORDER_ID
         where a.STATUS in ('1','2','3','5') 
         <if test="list.size() > 0">
              and b.PHONE_NUM in 
              <foreach item="numberList" collection="list" open="(" separator="," close=")">
                  #{numberList.num}
              </foreach>
         </if>
    </select>
    复制代码
    复制代码
    <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>
    复制代码

    foreach 元素的功能是非常强大的,它允许你指定一个集合,声明可以用在元素体内的集合项和索引变量。它也允许你指定开闭匹配的字符串以及在迭代中间放置分隔符。这个元素是很智能的,因此它不会偶然地附加多余的分隔符。

    注意 你可以将一个 List 实例或者数组作为参数对象传给 MyBatis,当你这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。List 实例将会以“list”作为键,而数组实例的键将是“array”。

    以上是结合http://mybatis.github.io/mybatis-3/zh/getting-started.html及自己开发中比较常用的总结出来的,今天给梳理一下,分享给大家!

    行走在设计师的路上!
     
    http://www.cnblogs.com/yolanda-lee/p/4552514.html
     
  • 相关阅读:
    大batch任务对structured streaming任务影响
    spark 集群优化
    linux神器 strace解析
    打个 hadoop RPC的栗子
    netty 入门
    c#硬件对接数值转换
    RabbitMQ 消息队列入门
    RabbitMQ 开发环境安装部署
    Nginx-4.Nginx如何处理请求
    Nginx-3.控制nginx
  • 原文地址:https://www.cnblogs.com/softidea/p/4553213.html
Copyright © 2020-2023  润新知