MyBatis的动态SQL

本文详细讲解了MyBatis中if、choose、foreach等标签的用法,涉及条件判断、动态列操作、集合遍历,以及trim和where/set的对比。通过实例演示了如何根据输入条件灵活构造SQL,提升代码复用和查询效率。
摘要由CSDN通过智能技术生成

MyBatis的动态SQL

1-if标签
1-在查询的时候-标签1
  1. 常用于update或者insert中选择性更新或者插入某个字段的值

  2. 案例:高级查询:只输入用户名,进行模糊查询,只输入邮箱,进行全匹配查询。两者都输入,进行匹配查询

  3. <select id="selectByUserWhere" resultType="sysUser">
           select *
           from sys_user
           <where>
               <if test="userName !=null and userName != ''">
                   and user_name like concat('%',#{userName},'%')
               </if>
               <if test="userEmail != null and userEmail != '' ">
                   and user_email = #{userEmail}
            </if>
           </where>
    
  4. 判断条件 property != null 或者 property ==null 适合任何类型的字段,用于判断属性值是否为空。 判断条件 property !=‘’ 或者property == ‘’ 只适合String类型的字段

  5. 注意1=1 这个条件:考虑如果两个条件都不满足,则sql语句是不对的

2-在update中的if
  1. 选择性更新某个字段,通过if实现动态列更新

  2. 选择性更新命名规范:方法名会以Selective作为后缀

  3. update sys_user
    set
    <if test="userName != null and userName != '' ">
    user_name = #{userName},
    </if>
    <if test="userPassword != null and userPassword !='' ">
    	user_password = #{userPassword},
    </if>
    id = #{id}
    where id = #{id}
    
  4. ==注意点:==第一点是每个if元素里面的SQL语句后面的逗号,第二点就是where关键字前面的id=#{id}

  5. 关于第二点:当全部的查询条件都是null或者空,如果有id=#{id}则为:update sys_user set id =#{id} where id = #{id},没有的话,sql语句则不完整。如果条件只有一个成立,没有id=#{id},sql语句也是不完整的

3-insert中使用if
  1. 目标:插入数据库中插入某一字段时,若用户输入为空,则使用数据库中的,否则使用用户输入的数据

  2. insert into sys_user(
    	user_name, user_password,
    	<if text= " userEmail !=null and userEmail != '' ">
    		user_email
    	</if>
    )values(
    	#{userName},#{userPassword},
    	<if test="userEmail != null and userEmail != '' ">
    		#{userEmail}
    	</if>
    )
    

在inser中使用时要注意,若在列的部分增加if条件,则values的部分也要增加相同的if条件,必须保证上下可以相互对应。

4-choose用法

if标签提供了基本的条件判断,但是无法实现if…else,的逻辑,要想实现这样的逻辑,就是用到choose 。。。when。。。otherwise标签

  1. 需求:当id有属性值的时候,优先使用id,当id无的时候判断用户名是否有值,都没有的时候sql无结果

  2. select id,userName,userPassword,userEmail,userInfo
    from sys_user
    where 1=1
    <choose>
    	<when test =" id !=null">
        	and id = #{id}
        </when>1
        <when test="userName != null and userName != ' '">
        	and user_name = #{userName}
        </when>
        <otherwise>
        	and 1=2
        </otherwise>
    </choose>
    
  3. 当且仅当 when全部为false 的时候,执行 otherwise 标签内的语句,所以 在使用 choose标签的时候,要思路清晰,否则会出现意料之外的事情

  4. 在以上查询中,如果没有otherwise 这个限制条件,所有的用户都会被查询出来,因为我们在对应的接口方法中使用了sysuser作为返回值,所以当实际查询结果是多个时就会报错

5-where 标签对比 标签1

where 和 set和 trim 这三个标签解决了类似的问题,并且where和set都属于 trim的一种具体用法。

  1. where标签的作用:如果该标签包含的元素中有返回值,就插入一个where ;如果where后面的字符串是以AND和OR开头的,就将他们剔除

  2. select id,userName,userPassword,userEmail
    from sys_user
    <where>
    	<if test=" userName != null and userName != ''">
        	and user_name like concat('%',#{userName},'%')
        </if>
        <if test=" userEmail != null and userEmail != ''">
        	and user_email = #{userEmail}
        </if>
    </where>
    
  3. where 标签和if标签同时使用的情况下,可以让sql更加的简洁,不会有where 1=1 这样的条件

6-set 用法对比2
  1. set标签的作用:如果给标签包含的元素中有返回值,就插入一个set,如果set后面字符串是以逗号结尾的,就将这个逗号去掉

  2. update sys_user
    <set>
    	<if test = "userName != null and userName != '' ">
        	user_name = #{userName},
        </if>
        <if test="userPassword != null and userPassword != ''  ">
        	user_password = #{userPassword},
        </if>
        where id = #{id}
    </set>
    
  3. 注意:在set标签用法中,sql后面的逗号没有问题了,但是如果set元素中没有内容,照样会出现sql错误,所以为了避免错误产生,类似id=#{id} 这样必然存在的赋值依然有保留的必要

7-trim用法
  1. where和set标签的功能都可以用trim标签实现,并且在底层就是通过TrimSqlNode实现的

  2. trim实现where标签和set标签的功能

  3. <trim prefix="where" prefixOverrides="and |or ">
    	....
    </trim>
    -- 这里的and 和or 后面的空格不能省去,避免匹配到andes orders等单词
    <trim prefix = "set" suffixOverrides = ",">
    	....
    </trim>
    
    
    
  4. trim 属性值

    1. prefix:当trim元素内包含内容时,会给内容增加prefix指定的前缀
    2. prefixOverrides:当trim元素内包含内容时,会把内容中匹配的前缀字符去掉
    3. suffix:当trim元素内包含内容的时候,会给内容增加suffix指定的后缀
    4. suffixOverrides: 当trim元素内包含内容时,会把内容中匹配的后缀字符串去掉
8-foreach实现in集合
  1. 需求:如何根据用户id集合查询出所有符合条件的用户

  2. select id, userPassword, userEmail
    from sys_user
    where id in 
    <foreach collection = "list" open="(" close=")" separator ="," item="id" index="i">
    	#{id}
    </foreach>
    
  3. 注意:当有多个参数的时候,要在dao接口的方法参数前加上@param注解给每个参数指定一个名字,否则的话,在sql中使用参数就会不方便,特别在foreach中

9-foreach实现批量插入
      <insert id="insertList">
        insert into sys_user(userName,userPassword,userEmail)
        values
        <foreach collection="list" item="user" separator=",">
            ( #{userName},#{userPassword},#{userEmail} )
        </foreach>
    </insert>
  1. 注意:通过item指定了循环变量名之后,在引用值的时候使用是“属性.属性” 的方式,如 user.userName
10-foreach实现动态update
  1. 参数类型是map时,foreach如何实现动态update

  2. 参数时map类型的时候,foreach标签的index属性值对应的不是索引值,而是map中的key

    <update id="updateByMap">
        update sys_user set
        <foreach collection="_parameter" item="val" index="key" separator=",">
            ${key} = #{key}
        </foreach>
        where id= #{id}
    </update>
  1. 注意:这里的key作为列名,对应的值作为该列的值,通过foreach将需要更新的字段拼接在sql语句中

批量操作

批量增加

 <insert id="insertBatch"  parameterType="list">
    insert into zx_client
    (
        ,phone,real_name,age,sex,id_no,id_addr
    ) values 
    <foreach collection="list"  item="item" open="(" separator="," close=")">
    (
        ,#{phone},#{realName},#{age},#{sex},#{idNo},#{idAddr}
     )
    </foreach>  
</insert>  

在这里插入图片描述

批量更新

<update id="updateOrderItem"  parameterType="java.util.List">
  <foreach collection="list" item="item"  separator=";">
    update order_item
    <set>
      <if test="item.orderId != null">
        order_id = #{item.orderId},
      </if>
      <if test="item.productId != null">
        product_id = #{item.productId},
      </if>
      <if test="item.count != null">
        count = #{item.count}
      </if>
    </set>
    where id = #{item.id}
  </foreach>
</update>

批量查询

   List<MRailwaystation> listRailwayStationlist( List<String> codeList);
       <select id="listRailwayStationlist" resultType="com.ceic.foundation.op.common.model.MRailwaystation">
        select * from m_railwaystation where railwaystation_id in
        <foreach collection="@Param没有加这个注解就写 list" item="item" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值