MyBatis动态SQL

1、什么是动态SQL?

理解:在MyBatis的SQL配置文件中需要对SQL语句进行动态的拼接

2、为什么需要动态SQL?

应用场景:多条件查询、批量删除、批量添加等等

比如:以"多条件查询"为例;假设:Car类,属性:id、carNum、carType、brand、guidePrice;前端页面需要查询car相关信息,可能根据car的brand查询,也可能根据car的brand和guidePrice查询,也可能不添加过滤条件全部查询;此时select查询语句中where子句后面添加的过滤条件是不确定的,所以需要动态SQL,对SQL语句进行动态拼接,只有满足相应条件才进行拼接;比如:这里前端如果想根据brand进行查询就在where子句后面添加brand=#{brand},如果前端想根据guidePrice查询,没有提交brand信息那么where子句后面就不会拼接brand=#{brand},只会拼接guide_Price=#{guidePrice}

3、如何使用动态SQL?

通过标签:if标签、where标签、trim标签、set标签、choose when otherwise标签、foreach标签、sql和include标签,进行SQL语句的动态拼接

3.1 <if>标签

​
    <select id="selectByMultiCondition" resultType="Car">
        select * from t_car where 1 = 1
        <!--
            1. if标签中test属性是必须的。
            2. if标签中test属性的值是false或者true。
            3. 如果test是true,则if标签中的sql语句就会拼接。反之,则不会拼接。
            4. test属性中可以使用的是:
                当使用了@Param注解,那么test中要出现的是@Param注解指定的参数名。@Param("brand"),那么这里只能使用brand
                当没有使用@Param注解,那么test中要出现的是:param1 param2 param3 arg0 arg1 arg2....
                当使用了POJO,那么test中出现的是POJO类的属性名。
            5. 在mybatis的动态SQL当中,不能使用&&,只能使用and。
        -->
        <if test="brand != null and brand != ''">
            and brand like "%"#{brand}"%"
        </if>
        <if test="guidePrice != null and guidePrice != ''">
            and guide_price > #{guidePrice}
        </if>
        <if test="carType != null and carType != ''">
            and car_type = #{carType}
        </if>
    </select>

​

3.2 <where>标签

1、所有条件都为空时,where标签保证不会生成where子句

2、自动去除某些条件前面多余的and或or

<select id="selectByMultiConditionWithWhere" resultType="car">
  select * from t_car
  <where>
    <if test="brand != null and brand != ''">
      and brand like #{brand}"%"
    </if>
    <if test="guidePrice != null and guidePrice != ''">
      and guide_price >= #{guidePrice}
    </if>
    <if test="carType != null and carType != ''">
      and car_type = #{carType}
    </if>
  </where>
</select>

3.3 <trim>标签

    <select id="selectByMultiConditionWithTrim" resultType="Car">
        select * from t_car
        <!--
            prefix:加前缀
            suffix:加后缀
            prefixOverrides:删除前缀
            suffixOverrides:删除后缀
        -->
        <!--prefix="where" 是在trim标签所有内容的前面添加 where-->
        <!--suffixOverrides="and|or" 把trim标签中内容的后缀and或or去掉-->
        <trim prefix="where" suffixOverrides="and|or">
            <if test="brand != null and brand != ''">
                brand like "%"#{brand}"%" or
            </if>
            <if test="guidePrice != null and guidePrice != ''">
                guide_price > #{guidePrice} and
            </if>
            <if test="carType != null and carType != ''">
                car_type = #{carType}
            </if>
        </trim>
    </select>

3.4 <set>标签

作用:

主要使用在update语句当中,用来生成set关键字,同时去掉最后多余的“,”

比如我们只更新提交的不为空的字段,如果提交的数据是空或者"",那么这个字段我们将不更新

    <update id="updateBySet">
        update t_car
        <set>
            <if test="carNum != null and carNum != ''">car_num = #{carNum},</if>
            <if test="brand != null and brand != ''">brand = #{brand},</if>
            <if test="guidePrice != null and guidePrice != ''">guide_price = #{guidePrice},</if>
            <if test="produceTime != null and produceTime != ''">produce_time = #{produceTime},</if>
            <if test="carType != null and carType != ''">car_type = #{carType},</if>
        </set>
        where
            id = #{id}
    </update>

3.5 choose when otherwise标签

语法格式:这三个标签是在一起使用的

<choose>
  <when></when>
  <when></when>
  <when></when>
  <otherwise></otherwise>
</choose>

语法格式类似于:只有一个分支会被选择

if(){
    
}else if(){
    
}else if(){
    
}else if(){
    
}else{

}

需求:先根据品牌查询,如果没有提供品牌,再根据指导价格查询,如果没有提供指导价格,就根据生产日期查询

<select id="selectWithChoose" resultType="car">
  select * from t_car
  <where>
    <choose>
      <when test="brand != null and brand != ''">
        brand like #{brand}"%"
      </when>
      <when test="guidePrice != null and guidePrice != ''">
        guide_price >= #{guidePrice}
      </when>
      <otherwise>
        produce_time >= #{produceTime}
      </otherwise>
    </choose>
  </where>
</select>

3.6 <foreach>标签

作用:循环数组或集合,动态生成sql

比如:批量删除

<!--
  foreach标签的属性:
      collection:指定数组或者集合
      item:代表数组或集合中的元素(item只是一个变量名,代表集合或者数组中的一个元素)
      separator:循环之间的分隔符
      open: foreach循环拼接的所有sql语句的最前面以什么开始。
      close: foreach循环拼接的所有sql语句的最后面以什么结束。

  collection="ids" 第一次写这个的时候报错了,错误信息是:[array, arg0]
  什么意思?
      map.put("array", 数组);
      map.put("arg0", 数组);
-->
<delete id="deleteByIds">
  <!--
  delete from t_car where id in(
  <foreach collection="ids" item="aaaaaaa" separator=",">
      #{aaaaaaa}
  </foreach>
  )
  -->
  delete from t_car where id in
  <foreach collection="ids" item="id" separator="," open="(" close=")">
      #{id}
  </foreach>
</delete>

上面通过in关键字进行批量删除,也可以使用or关键字

<delete id="deleteBatchByForeach2">
  delete from t_car where
  <foreach collection="ids" item="id" separator="or">
    id = #{id}
  </foreach>
</delete>

比如:批量添加

<insert id="insertBatchByForeach">
  insert into t_car values 
  <foreach collection="cars" item="car" separator=",">
    (null,#{car.carNum},#{car.brand},#{car.guidePrice},#{car.produceTime},#{car.carType})
  </foreach>
</insert>

3.7 sql标签和include标签

作用:

1.sql标签用来声明sql片段

2.include标签用来将声明的sql片段包含到某个sql语句当中

3.代码复用。易维护

<sql id="carCols">id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType</sql>

<select id="selectAllRetMap" resultType="map">
  select <include refid="carCols"/> from t_car
</select>

<select id="selectAllRetListMap" resultType="map">
  select <include refid="carCols"/> carType from t_car
</select>

<select id="selectByIdRetMap" resultType="map">
  select <include refid="carCols"/> from t_car where id = #{id}
</select>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值