当前位置: 代码网 > it编程>编程语言>Java > 实测对比MyBatis五种批量新增数据方法耗时排行

实测对比MyBatis五种批量新增数据方法耗时排行

2026年08月18日 Java 我要评论
一、准备工作1、导入pom.xml依赖 <dependencies> <dependency> <groupid>org.

一、准备工作

1、导入pom.xml依赖

    <dependencies>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
        </dependency>
        <!-- mysql驱动依赖 -->
        <dependency>
            <groupid>mysql</groupid>
            <artifactid>mysql-connector-java</artifactid>
            <version>8.0.29</version>
        </dependency>
        <!--mybatis依赖-->
        <dependency>
            <groupid>org.mybatis.spring.boot</groupid>
            <artifactid>mybatis-spring-boot-starter</artifactid>
            <version>2.2.2</version>
        </dependency>
        <!--mybatis-plus依赖-->
        <dependency>
            <groupid>com.baomidou</groupid>
            <artifactid>mybatis-plus-boot-starter</artifactid>
            <version>3.5.2</version>
        </dependency>
        <!-- lombok依赖 -->
        <dependency>
            <groupid>org.projectlombok</groupid>
            <artifactid>lombok</artifactid>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-test</artifactid>
            <scope>test</scope>
        </dependency>
    </dependencies>

2、配置yml文件

server:
  port: 8080
spring:
  datasource:
    username: root(用户名)
    password: root(密码)
    url: jdbc:mysql://localhost:3306/test(数据库名字)?useunicode=true&characterencoding=utf-8&usessl=false&servertimezone=utc
    driver-class-name: com.mysql.cj.jdbc.driver
mybatis:
  mapper-locations: classpath:mapping/*.xml

3、公用的user类

@data
public class user {
 
    private int id;
    private string username;
    private string password;
}

二、mybatis利用for循环批量插入

1、编写userservice服务类

测试一万条数据耗时情况

@service
public class userservice {
 
    @resource
    private usermapper usermapper;
 
    public void insertusers(){
        long start = system.currenttimemillis();
        for(int i = 0 ;i < 10000; i++) {
            user user = new user();
            user.setusername("name" + i);
            user.setpassword("password" + i);
            usermapper.insertusers(user);
        }
        long end = system.currenttimemillis();
        system.out.println("一万条数据总耗时:" + (end-start) + "ms" );
    }
 
}

2、编写usermapper接口

@mapper
public interface usermapper {
 
    integer insertusers(user user);
}

3、编写usermapper.xml文件

<?xml version="1.0" encoding="utf-8" ?>
<!doctype mapper
        public "-//mybatis.org//dtd mapper 3.0//en"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ithuang.demo.mapper.usermapper">
    <insert id="insertusers">
        insert into user (username, password)
        values(#{username}, #{password})
    </insert>
</mapper>

4、进行单元测试

@springboottest
class demoapplicationtests {
 
    @resource
    private userservice userservice;
 
    @test
    public void insert(){
        userservice.insertusers();
    }
 
}

5、结果输出

一万条数据总耗时:26348ms

三、mybatis的手动批量提交

1、其他保持不变

service层作稍微的变化

@service
public class userservice {
 
    @resource
    private usermapper usermapper;
 
    @resource
    private sqlsessiontemplate sqlsessiontemplate;
 
    public void insertusers(){
        //关闭自动提交
        sqlsession sqlsession = sqlsessiontemplate.getsqlsessionfactory().opensession(executortype.batch, false);
        usermapper usermapper = sqlsession.getmapper(usermapper.class);
        long start = system.currenttimemillis();
        for(int i = 0 ;i < 10000; i++) {
            user user = new user();
            user.setusername("name" + i);
            user.setpassword("password" + i);
            usermapper.insertusers(user);
        }
        sqlsession.commit();
        long end = system.currenttimemillis();
        system.out.println("一万条数据总耗时:" + (end-start) + "ms" );
    }
 
}

2、结果输出

一万条数据总耗时:24516ms

四、mybatis以集合方式批量新增

1、编写userservice服务类

@service
public class userservice {
 
    @resource
    private usermapper usermapper;
 
    public void insertusers(){
        long start = system.currenttimemillis();
        list<user> userlist = new arraylist<>();
        user user;
        for(int i = 0 ;i < 10000; i++) {
            user = new user();
            user.setusername("name" + i);
            user.setpassword("password" + i);
            userlist.add(user);
        }
        usermapper.insertusers(userlist);
        long end = system.currenttimemillis();
        system.out.println("一万条数据总耗时:" + (end-start) + "ms" );
    }
 
}

3、编写usermapper接口

@mapper
public interface usermapper {
 
    integer insertusers(list<user> userlist);
}

4、编写usermapper.xml文件

<?xml version="1.0" encoding="utf-8" ?>
<!doctype mapper
        public "-//mybatis.org//dtd mapper 3.0//en"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ithuang.demo.mapper.usermapper">
    <insert id="insertusers">
        insert into user (username, password)
        values
        <foreach collection ="userlist" item="user" separator =",">
            (#{user.username}, #{user.password})
        </foreach>
    </insert>
</mapper>

以下完整且规范的写法

注:如果需要mysql支持批量操作需要在yml的url配置中新增allowmultiqueries=true,支持以;分隔批量执行sql。

例如:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?allowmultiqueries=true&usessl=false
    username: 
    password: 

完整代码:

<insert id="insertuserbatch">
        <foreach collection ="list" item="item" separator =";">
            insert into user
            <trim prefix="(" suffix=")" suffixoverrides=",">
                <if test="item.id != null and item.id != ''">id,</if>
                <if test="item.username != null and item.username != ''">username,</if>
                <if test="item.password != null and item.password != ''">password,</if>
                <if test="item.sex != null and item.sex != ''">sex,</if>
                <if test="item.age != null">age,</if>
                <if test="item.address != null and item.address != ''">address,</if>
                <if test="item.createtime != null">create_time,</if>
            </trim>
            values
            <trim prefix="(" suffix=")" suffixoverrides=",">
                <if test="item.id != null and item.id != ''">#{item.id},</if>
                <if test="item.username != null and item.username != ''">#{item.username},</if>
                <if test="item.password != null and item.password != ''">#{item.password},</if>
                <if test="item.sex != null and item.sex != ''">#{item.sex},</if>
                <if test="item.age != null">#{item.age},</if>
                <if test="item.address != null and item.address != ''">#{item.address},</if>
                <if test="item.createtime != null">#{item.createtime},</if>
            </trim>
        </foreach>
    </insert>

5、输出结果

一万条数据总耗时:521ms

五、mybatis-plus提供的savebatch方法

1、编写userservice服务

@service
public class userservice extends serviceimpl<usermapper, user> implements iservice<user> {
 
    public void insertusers(){
        long start = system.currenttimemillis();
        list<user> userlist = new arraylist<>();
        user user;
        for(int i = 0 ;i < 10000; i++) {
            user = new user();
            user.setusername("name" + i);
            user.setpassword("password" + i);
            userlist.add(user);
        }
        savebatch(userlist);
        long end = system.currenttimemillis();
        system.out.println("一万条数据总耗时:" + (end-start) + "ms" );
    }
}

2、编写usermapper接口

@mapper
public interface usermapper extends basemapper<user> {
 
}

3、单元测试结果

一万条数据总耗时:24674ms

注:

这边我没有开启rewritebatchedstatements=true,所以会非常慢,开启的话我实测过,耗时为707ms,这个参数的作用是启用批处理语句的重写功能,这对提高使用jdbc批量更新语句的性能有很大帮助。

mybatis-plus的savebatch方法默认使用jdbc的addbatch()和executebatch()方法实现批量插入。但是部分数据库的jdbc驱动并不支持addbatch(),这样每次插入都会发送一条sql语句,严重影响了批量插入的性能。

设置rewritebatchedstatements=true后,mybatis-plus会重写插入语句,将其合并为一条sql语句,从而减少网络交互次数,提高批量插入的效率。

需要加在yml配置文件中:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?rewritebatchedstatements=true&usessl=false
    username: root
    password: root

六、mybatis-plus提供的insertbatchsomecolumn方法

1、编写easysqlinjector 自定义类

public class easysqlinjector extends defaultsqlinjector {
 
 
    @override
    public list<abstractmethod> getmethodlist(class<?> mapperclass, tableinfo tableinfo) {
        // 注意:此sql注入器继承了defaultsqlinjector(默认注入器),调用了defaultsqlinjector的getmethodlist方法,保留了mybatis-plus的自带方法
        list<abstractmethod> methodlist = super.getmethodlist(mapperclass, tableinfo);
        methodlist.add(new insertbatchsomecolumn(i -> i.getfieldfill() != fieldfill.update));
        return methodlist;
    }
 
}

2、定义核心配置类注入此bean

@configuration
public class mybatisplusconfig {
 
    @bean
    public easysqlinjector sqlinjector() {
        return new easysqlinjector();
    }
}

3、编写userservice服务类

public class userservice{
 
    @resource
    private usermapper usermapper;
    public void insertusers(){
        long start = system.currenttimemillis();
        list<user> userlist = new arraylist<>();
        user user;
        for(int i = 0 ;i < 10000; i++) {
            user = new user();
            user.setusername("name" + i);
            user.setpassword("password" + i);
            userlist.add(user);
        }
        usermapper.insertbatchsomecolumn(userlist);
        long end = system.currenttimemillis();
        system.out.println("一万条数据总耗时:" + (end-start) + "ms" );
    }
}

4、编写easybasemapper接口

public interface easybasemapper<t> extends basemapper<t> {
    /**
     * 批量插入 仅适用于mysql
     *
     * @param entitylist 实体列表
     * @return 影响行数
     */
    integer insertbatchsomecolumn(collection<t> entitylist);
}

5、编写usermapper接口

@mapper
public interface usermapper<t> extends easybasemapper<user> {
    
}

6、单元测试结果

一万条数据总耗时:575ms

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com