• Mybatis入门之实现简单批量插入(insert)、删除(delete)、更新(update)


    插入和删除很简单,而更新有很多不同的情景

    我的表结构:

    插入和删除 

    mapper的xml映射文件,直接放代码套了就能用,BookVO中有一个books集合存放数据:

        <!-- 实现批量插入 -->
        <insert id="insertBooksBatch" parameterType="com.star.vo.BookVO">
            insert into t_book_vue(bookname,booktype,price)
            <trim prefix="values " suffixOverrides=",">
                <foreach collection="books" separator="," item="book">
                    (#{book.bookname},#{book.booktype},#{book.price})
                </foreach>
            </trim>
        </insert>
        <!-- 实现批量删除 -->
        <delete id="deleteBookBatch" parameterType="com.star.vo.BookVO">
            DELETE
            FROM
            t_book_vue WHERE id in
            <foreach collection="books" open="(" close=")" item="book" separator=",">
                #{book.id}
            </foreach>
        </delete>

    更新

    如果要更新多条记录为同样的数据,则可以用:

    UPDATE t_book_vue SET bookname = 'course1',price=123.22 WHERE id in ('id1', 'id2', 'id3);

    更新多条记录的多个字段为不同的值,是比较常用的场景,比较普通的写法就是循环更新sql,一次执行多条更新语句,那么mapper映射文件写法应该如下:

        <update id="updateBookBatch"  parameterType="java.util.List">
            <foreach collection="list" item="item" separator=";">
                update t_book_vue
                <set>
                    bookname=#{item.bookname},price=#{item.price}
                </set>
                where id = ${item.id}
            </foreach>
        </update>

    要注意的是,此种方式要想成功,必须在数据库连接url最后面带上一个允许执行多次的参数(例如: jdbc:mysql://localhost:3306/mysqlTest?characterEncoding=utf-8&allowMultiQueries=true):

    &allowMultiQueries=true

    另一种方式为sql的case when语法实现批量插入,最终只会产生一条sql,数据量过大可能引起巨大的开销(拼接sql过程复杂):

        <!-- 实现批量更新(利用case when) -->
        <update id="updateBookBatch" parameterType="com.star.vo.BookVO">
            update t_book_vue
            <trim prefix="set" suffixOverrides=",">
                <foreach collection="books" open="bookname = case" close="end," item="i">
                    <if test="i.id!=null and i.bookname!=null">
                        when id=#{i.id} then #{i.bookname}
                    </if>
                </foreach>
                <foreach collection="books" open="price =case" close="end," item="i">
                    <if test="i.id!=null and i.price!=null">
                        when id=#{i.id} then #{i.price}
                    </if>
                </foreach>
                <foreach collection="books" open="booktype =case" close="end," item="i">
                    <if test="i.id!=null and i.booktype!=booktype">
                        when id=#{i.id} then #{i.booktype}
                    </if>
                </foreach>
            </trim>
            where
            <foreach collection="books" separator="or" item="i" index="index">
                id=#{i.id}
            </foreach>
        </update>

    最后一种Mysql独有的语法:duplicate key update效率是最高的,通过批量插入检查,如果已存在,则更新,所以可以变相达到批量修改的效果,但是一般大公司都禁用,公司一般都禁止使用REPLACE INTO和INSERT INTO … ON DUPLICATE KEY UPDATE,因为这种sql有可能会造成数据丢失和主从上表的自增id值不一致。

    比如这句sql:

    INSERT INTO t_book_vue(id,bookname,price,booktype)VALUES(67,'你好',123.23,'1-4'),(66,'不好',321.32,'1-6') ON DUPLICATE KEY UPDATE 
    bookname=VALUES(bookname),price=VALUES(price),booktype = VALUES(booktype);

    它的执行结果:

     我们在插入的时候发现了已经存在的主键,所以它执行了覆盖操作,变相的达到了更新的目的所以影响行数为4(如果均未发现主键则是2),此表中必须有唯一索引或主键,否则会产生上述问题。

     在mybatis中实现如下,参考完整源码移步:Mybatis案例

        <insert id="updateBookBatch" parameterType="com.star.vo.BookVO">
            INSERT INTO t_book_vue(id,bookname,price,booktype)VALUES
            <foreach collection="books" item="item" separator=",">
                (#{item.id},#{item.bookname},#{item.price},#{item.booktype})
            </foreach>
            ON DUPLICATE KEY UPDATE
            bookname=VALUES(bookname),price=VALUES(price),booktype=VALUES(booktype)
        </insert>
  • 相关阅读:
    「SAM」你的名字
    「疫期颓废」2
    「疫期颓废」1
    代码覆盖率简单介绍
    解决git报ssh variant 'simple' does not support setting port
    接口自动化基本流程和测试思路
    wait和sleep的区别
    vm垃圾回收算法的简单理解
    TCP-三次握手和四次挥手简单理解
    浏览器输入一个url 中间经历的过程
  • 原文地址:https://www.cnblogs.com/StarChen20/p/13943924.html
Copyright © 2020-2023  润新知