• Mybatis批量插入或更新数据


    对于大量的数据,使用批量插入或修改可以提高效率。原因是批量添加或修改是执行一条sql语句,传入多个值,可以减少与数据库的访问次数,从而会提高效率。下面分别介绍Oracle和MySQL的用法:

    1.Oracle批量插入数据

    对于集合类型的数据,在插入时会使用mybatis的<foreach>标签,那么正确的用法如下:

    <insert id="insertUserBatch">
    insert into user(id,name,password,addr)
    select user_seq.nextval,a.* from(
    <foreach collection="list" item="item" open="(" close=")" separator="union all">
    select
    #{item.name},
    #{item.password},
    #{item.addr}
    from dual
    </foreach>
    ) a
    </insert>

    以上语句是向user表循环查询数据,传递的参数是List<User>类型的集合。

    需要注意是的,在使用时,分隔符separator必须是union all。

    2.MySQL批量插入数据

    对于集合类型的数据,在插入时会使用mybatis的<foreach>标签,那么mysql的批量插入数据sql如下:

    <insert id="insertBatch">
    insert into user(name,password,addr)
    values
    <foreach collection="list" item="item" separator=",">
    (
    #{item.name},
    #{item.password},
    #{item.addr}
    )
    </foreach>
    </insert>

    和oracle的语句相比,没有指定主键,原因是主键id使用了自增。在foreach中里面的两个括号不能省略,要使用逗号作为分隔符。

    3.Mybatis的trim标签

    3.1功能属性表

    trim标签的功能属性如下表:

    属性名 说明
    prefix 在sql语句前面拼接的字符串
    suffix 在sql语句后面拼接的字符串
    prefixOverrides 去除sql语句前面指定的字符或者关键字
    suffixOverrides 去除sql语句后面指定的字符或者关键字

    3.2去除多余的and关键字

    1)先看下面最原始的sql:

    <select id="findActiveBlogLike">
      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>

    若这些条件没有一个能匹配上,那么这条 SQL 会变成:

    SELECT * FROM BLOG
    WHERE

    2)这种sql肯定会导致异常的出现。如果仅仅第二个条件匹配,那么这条 SQL 最终的样子:

    SELECT * FROM BLOG
    WHERE 
    AND title like '%aaa%'

    这种sql就多了一个and关键字,也会导致异常的发生。

    3)对于mybatis而言,可以使用where标签来解决上述的问题,其sql如下:

    <select id="findActiveBlogLike">
      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 like #{author}
        </if>
      </where>
    </select>

    4)除此之外,mybatis还提供了另一个标签trim,可以用其来去除多余的关键字,上一步的代码使用trim如下:

    <select id="findActiveBlogLike">
      SELECT * FROM BLOG 
      <trim prefix="WHERE" prefixOverrides="AND">
        <if test="state != null">
          state = #{state}
        </if> 
        <if test="title != null">
          AND title like #{title}
        </if>
        <if test="author != null">
          AND author like #{author}
        </if>
      </trim>
    </select>

    上述的sql中,当条件中没有匹配的数据时,不会添加where关键字;当匹配到条件时,会在前面拼接where关键字,若匹配的条件前面有and,那么会自动去掉and关键字。举例说明,条件的内容只作为说明:

    A:当state、title、author都为NULL时,查询语句是

    SELECT * FROM BLOG 

    B:当title、author都为NULL而state不为NULL时,查询语句是:

    SELECT * FROM BLOG
    where state = 1

    C:当state、author都为NULL而title不为NULL时,去除了多余的and关键字,查询语句是:

    SELECT * FROM BLOG
    where title like '%aaa%'

    D:当state、title都不为NULL而author为NULL时,查询语句是:

    SELECT * FROM BLOG
    where state = 1
    and title like '%aaa%'

    3.3去除多余的逗号

     1)先看下面的sql:

    <insert id="insertBlogSelective">
      insert into BLOG 
      (  
        <if test="state != null">
             state</if> 
        <if test="title != null">
            title,
        </if>
        <if test="author != null">
            author
        </if>
       )
       values(
        <if test="state != null">
            #{state},
        </if> 
        <if test="title != null">
            #{title},
        </if>
        <if test="author != null">
            #{author}
        </if>
       )
    </insert >

    若这些条件中author没有匹配上,那么这条 SQL 会变成:

    insert into BLOG(state,title,) values(1,'mysql入门',);

    明显看出多了两个逗号,会导致异常。使用trim标签解决如下:

    <insert id="insertBlogSelective">
      insert into BLOG 
      <trim prefix="(" suffix=")" suffixOverrides=",">  
        <if test="state != null">
             state
        </if> 
        <if test="title != null">
            title,
        </if>
        <if test="author != null">
            author
        </if>
       </trim>
       <trim prefix="values(" suffix=")" suffixOverrides=",">  
        <if test="state != null">
            #{state},
        </if> 
        <if test="title != null">
            #{title},
        </if>
        <if test="author != null">
            #{author}
        </if>
       </trim>
    </insert >

    上述的sql中,当条件中没有匹配的数据时,不会插入对应的列数据。主要是使用suffixOverrides属性,当条件不满足时会删除结尾多余的逗号。

    4.Oracle批量修改数据

     当数据量很大时,使用批量修改可以提高效率。看下面对用户信息进行批量修改:

       <update id="updateBatch">
            update user t
            <trim prefix="set" suffixOverrides=",">
                <trim prefix="name  = case" suffix="end ,">
                    <foreach collection="list" item="item">
                        <if test="item.name != null ">
                            when t.id = #{item.id} then #{item.name}
                        </if>
                    </foreach>
                </trim>
                <trim prefix="password  = case" suffix="end ,">
                    <foreach collection="list" item="item">
                        <if test="item.password != null ">
                            when t.id = #{item.id} then #{item.password}
                        </if>
                    </foreach>
                </trim>
                <trim prefix="addr  = case" suffix="end ,">
                    <foreach collection="list" item="item">
                        <if test="item.addr != null ">
                            when t.id = #{item.id} then #{item.addr}
                        </if>
                    </foreach>
                </trim>
            </trim>
            where id in
            <foreach collection="list" item="item" open="(" close=")" separator=",">
                #{item.id}
            </foreach>
        </update>

    使用了trim标签,生成的完整的sql如下,为了说明方便仅对三条数据进行修改,批量的数据是类似的:

    update user t set 
      name = case 
         when t.id = ? then ? 
         when t.id = ? then ? 
         when t.id = ? then ? end , 
      password = case 
             when t.id = ? then ? 
             when t.id = ? then ? 
             when t.id = ? then ? end , 
      addr = case 
         when t.id = ? then ? 
         when t.id = ? then ?
         when t.id = ? then ? end 
    where id in ( ? , ? , ? )

    在上述的sql中,使用了两层的trim标签,外层的标签添加了前缀"set"关键字,另外如果有多余的逗号则会删除。内层的trim对应一个字段,当此字段不为null时才会包含内部的代码;也使用了case when关键字。下面对几种情况进行分析:

    A:name为NULL,其他属性不为NULL时,实际的语句如下:

    update user t set 
      password = case 
             when t.id = ? then ? 
             when t.id = ? then ? 
             when t.id = ? then ? end , 
      addr = case 
         when t.id = ? then ? 
         when t.id = ? then ?
         when t.id = ? then ? end 
    where id in ( ? , ? , ? )

    当属性为NULL时,此字段便不会被添加到sql语句当中,上述这种情况就是很好的说明。

    B:password为NULL,其他属性不为NULL时,实际的语句

    update user t set 
      name = case 
         when t.id = ? then ? 
         when t.id = ? then ? 
         when t.id = ? then ? end , 
      addr = case 
         when t.id = ? then ? 
         when t.id = ? then ?
         when t.id = ? then ? end 
    where id in ( ? , ? , ? )

    C:addr为NULL,其他属性不为NULL时,实际的语句

    update user t set 
      name = case 
         when t.id = ? then ? 
         when t.id = ? then ? 
         when t.id = ? then ? end , 
      password = case 
             when t.id = ? then ? 
             when t.id = ? then ? 
             when t.id = ? then ? end 
    where id in ( ? , ? , ? )

    由于addr的前面有其他的trim,那么当addr为NULL时,就会自动删除关键字'end"后面的逗号。

    5.MySQL批量修改数据

    MySQL的修改语法和oracle的语法基本类似,批量修改的语句可直接参考oracle的批量修改。

    就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
  • 相关阅读:
    matplotlib的使用——scatter散点图的绘制
    OpenCVPython系列之立体图像的深度图
    YOLOv3 cfg文件详解
    Opencv的使用小教程2——Opencv常用图像处理函数汇总
    数字世界中的纸张——理解 PDF
    go channel初步
    Unity学习记录 导航
    elasticsearch的keyword与text的区别
    markdownitcontainer
    Windows 编译opensll
  • 原文地址:https://www.cnblogs.com/zys2019/p/14686679.html
Copyright © 2020-2023  润新知