java Mybatis-Plus之实现批量插入

使用batchSave

Mybatis-Plus提供了IService接口,里面提供了batchSave方法,即批量保存方法

创建Service接口

创建一个基继承了Mybatis-Plus提供的IService接口的接口

public interface TestService extends IService<T> 

创建Service实现类

创建一个实现类,继承Mybatis-Plus提供的ServiceImpl类,以及实现上面创建的接口

public class TestServiceImpl extends ServiceImpl<M extends BaseMapper<T>, T> implements TestService

注意

虽然可以使用batchSave实现批量插入,但是插入时频繁请求数据库,看了看方法,batchSave方法是一条条请求插入到数据库的,这样效率太低,且影响数据库的使用

自定义方法

Mapper编写自定义的sql

通过在Mapper编写自定义的sql方法实现批量插入

@Insert("<script>" +
        "INSERT INTO T_TEST(id,content,created_time)VALUES" +
        "<foreach collection='testDetails' item='testDetail'   separator=','> " +
        "(#{testDetail.id},#{testDetail.content},#{testDetail.createdTime})" +
        "</foreach> " +
        "</script>")//
boolean insertBatch(@Param("testDetails") List<TestBean> testBeanList);

或 mapper.xml


或

<insert id="insertBatch">
        INSERT INTO `u_miduo_code_relation` (
            `pid`,
            `order_source`,
            `order_source_name`,
            `order_direct`,
            `order_direct_name`,
            `order_no`,
            `code`,
            `tag_type`,
            `biggerserialnumber`,
            `bigserialnumber`,
            `mediumserialnumber`,
            `smallserialnumber`,
            `distributor_code`,
            `distributor_name`,
            `batch`,
            `prod_id`,
            `prod_name`,
            `specification`,
            `product_code`,
            `product_name`,
            `product_norm`,
            `sale_num`,
            `sale_time`,
            `sale_warehouse`,
            `operator`,
            `create_time`
        )
        VALUES
        <foreach collection="itemList" item="item" index="index" open="" close="" separator=",">
            (#{item.pid},
            #{item.orderSource},
            #{item.orderSourceName},
            #{item.orderDirect},
            #{item.orderDirectName},
            #{item.orderNo},
            #{item.code},
            #{item.tagType},
            #{item.biggerserialnumber},
            #{item.bigserialnumber},
            #{item.mediumserialnumber},
            #{item.smallserialnumber},
            #{item.distributorCode},
            #{item.distributorName},
            #{item.batch},
            #{item.prodId},
            #{item.prodName},
            #{item.specification},
            #{item.productCode},
            #{item.productName},
            #{item.productNorm},
            #{item.saleNum},
            #{item.saleTime},
            #{item.saleWarehouse},
            #{item.operator},
            #{item.createTime})
        </foreach>
    </insert>

使用动态标签循环拼接参数,但是在这之后,我又发现了一个问题,但数据量太多,拼接出来的语句太长导致内存溢出。

分批量操作

需要引入Lists的依赖

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.1-jre</version>
</dependency>

当数据量达到一定阈值时,按照一定数据量分组,分批次插入数据。

		List<List<MiduoCodeRelation>> lists = Lists.partition(miduoCodeRelations, 100);
		lists.forEach(itemList->miduoCodeRelationMapper.insertBatch(itemList));

MyBatis-plus批量写入数据方法saveBatch速度很慢原因排查

MySQL的JDBC连接的url中要加rewriteBatchedStatements参数,并保证5.1.13以上版本的驱动,才能实现高性能的批量插入。
MySQL JDBC驱动在默认情况下会无视executeBatch()语句,把我们期望批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,批量插入实际上是单条插入,直接造成较低的性能。
只有把rewriteBatchedStatements参数置为true, 驱动才会帮你批量执行SQL
另外这个选项对INSERT/UPDATE/DELETE都有效

解决方案:

在jdbc连接url最后加上jdbc:mysql://127.0.0.1:3306/dev?rewriteBatchedStatements=true,测试发现速度果然提升

posted on 2023-04-22 00:31  何苦->  阅读(562)  评论(0编辑  收藏  举报

导航