mybatis三种批量插入方式性能对比

准备:

 1.表结构

 

CREATE TABLE `t_user` (
  `id` varchar(32) CHARACTER SET utf8 NOT NULL COMMENT '主键',
  `name` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT '用户名',
  `del_flag` char(1) CHARACTER SET utf8 DEFAULT NULL COMMENT '删除标示',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

 

 2.1 jdbc.properties配置

 

mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://127.0.0.1:3306/ssm
mysql.username=root
mysql.password=admin
#定义初始连接数
mysql.initialSize=1
#定义最大连接数
mysql.maxActive=20
#定义最大空闲
mysql.maxIdle=20
#定义最小空闲
mysql.minIdle=1
#定义最长等待时间
mysql.maxWait=60000


 2.2 spring-mybatis.xml配置

 

<context:component-scan base-package="com.win.ssm"/>
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${mysql.driver}"/>
    <property name="url" value="${mysql.url}"/>
    <property name="username" value="${mysql.username}"/>
    <property name="password" value="${mysql.password}"/>
    <!-- 初始化链接大小-->
    <property name="initialSize" value="${mysql.initialSize}"/>
    <!-- 连接池最大数量-->
    <property name="maxActive" value="${mysql.maxActive}"/>
    <!-- 连接池最大空闲-->
    <property name="maxIdle" value="${mysql.maxIdle}"/>
    <!-- 连接池最小空闲 -->
    <property name="minIdle" value="${mysql.minIdle}"></property>
    <!-- 获取连接最大等待时间-->
    <property name="maxWait" value="${mysql.maxWait}"/>
</bean>
<!-- springmybatis整合类 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <!-- 查找接口的别名 -->
    <property name="typeAliasesPackage" value="com.win"/>
    <!-- 自动扫描mapping.xml文件-->
    <property name="mapperLocations" value="classpath:/mapping/*.xml"/>
</bean>

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg index="0" ref="sqlSessionFactory" />
    <!--<constructor-arg index="1" value="BATCH" />-->
</bean>

<!-- 扫描DAO接口 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.win.ssm.dao"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!-- 事务管理 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

 

第一种:普通for循环插入

 ①junit类

 

@Test
public void testInsertBatch2() throws Exception {
    long start = System.currentTimeMillis();
    User user;
    SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(false);
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    for (int i = 0; i < 500; i++) {
        user = new User();
        user.setId("test" + i);
        user.setName("name" + i);
        user.setDelFlag("0");
        mapper.insert(user);
    }
    sqlSession.commit();
    long end = System.currentTimeMillis();
    System.out.println("---------------" + (start - end) + "---------------");
}

 ②xml配置

 

<insert id="insert">
    INSERT INTO t_user (id, name, del_flag)
          VALUES(#{id}, #{name}, #{delFlag})
</insert>

 

第二种:mybatis BATCH模式插入

 ①junit类

 

@Test
public void testInsertBatch2() throws Exception {
    long start = System.currentTimeMillis();
    User user;
    SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);//跟上述sql区别
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    for (int i = 0; i < 500; i++) {
        user = new User();
        user.setId("test" + i);
        user.setName("name" + i);
        user.setDelFlag("0");
        mapper.insert(user);
    }
    sqlSession.commit();
    long end = System.currentTimeMillis();
    System.out.println("---------------" + (start - end) + "---------------");
}

 

  ②xml配置与第一种②中使用相同

第三种:foreach方式插入

 ①junit类

 

@Test
public void testInsertBatch() throws Exception {
    long start = System.currentTimeMillis();
    List<User> list = new ArrayList<>();
    User user;
    for (int i = 0; i < 10000; i++) {
        user = new User();
        user.setId("test" + i);
        user.setName("name" + i);
        user.setDelFlag("0");
        list.add(user);
    }
    userService.insertBatch(list);
    long end = System.currentTimeMillis();
    System.out.println("---------------" + (start - end) + "---------------");
}

②xml配置

 

<insert id="insertBatch">
    INSERT INTO t_user
            (id, name, del_flag)
    VALUES
    <foreach collection ="list" item="user" separator =",">
         (#{user.id}, #{user.name}, #{user.delFlag})
    </foreach >
</insert>


特别注意:mysql默认接受sql的大小是1048576(1M),即第三种方式若数据量超过1M会报如下异常:(可通过调整MySQL安装目录下的my.ini文件中[mysqld]段的"max_allowed_packet = 1M")

 

nested exception is com.mysql.jdbc.PacketTooBigException: Packet for query is too large (5677854 > 1048576).

You can change this value on the server by setting the max_allowed_packet' variable.


结果对比:

 

 第一种第二种第三种
500条77427388622
1000条1529015078746
5000条780111773501172
10000条3974722011801205

时间有限测试数据较少,有兴趣可以自己测试以下。(不清楚为什么BATCH有时候比单条循环插入还耗时间)

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: Mybatis-Plus提供了批量插入和更新的功能,可以大大提高数据操作的效率。 批量插入可以使用Mybatis-Plus提供的insertBatch方法,将多条记录一次性插入到数据库中。示例代码如下: List<User> userList = new ArrayList<>(); // 添加多条记录到userList中 userMapper.insertBatch(userList); 批量更新可以使用Mybatis-Plus提供的updateBatchById方法,将多条记录一次性更新到数据库中。示例代码如下: List<User> userList = new ArrayList<>(); // 修改多条记录的信息 userMapper.updateBatchById(userList); 需要注意的是,批量插入和更新的记录数不能太大,否则可能会导致数据库性能下降。建议在实际应用中根据具体情况进行调整。 ### 回答2: Mybatis-plus是一款基于Mybatis的增强工具,它提供了许多实用的功能来简化开发,其中就包括批量插入更新操作。 在实现批量插入更新操作时,我们通常会遵循以下步骤: 1. 创建一个实体类,该实体类需要继承Mybatis-plus提供的Model类,并定义需要插入或更新的字段属性。 2. 创建一个Mapper接口,该接口需要继承Mybatis-plus提供的BaseMapper接口,并定义批量插入或更新的方法。 3. 在该Mapper接口中实现批量插入或更新操作的SQL语句。 4. 在Service中调用Mapper接口中的批量插入或更新方法,传入需要插入或更新的数据集合即可。 下面是一个示例代码: 1. 定义一个实体类: ``` @Data @TableName("user") public class User extends Model<User> { @TableId(value = "id", type = IdType.AUTO) private Long id; private String name; private Integer age; } ``` 2. 创建一个Mapper接口: ``` public interface UserMapper extends BaseMapper<User> { void batchInsert(List<User> userList); void batchUpdate(List<User> userList); } ``` 3. 实现批量插入或更新操作的SQL语句: ``` public void batchInsert(List<User> userList) { SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH); UserMapper mapper = sqlSession.getMapper(UserMapper.class); for (User user : userList) { mapper.insert(user); } sqlSession.flushStatements(); sqlSession.commit(); sqlSession.clearCache(); } ``` ``` public void batchUpdate(List<User> userList) { SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH); UserMapper mapper = sqlSession.getMapper(UserMapper.class); for (User user : userList) { mapper.updateById(user); } sqlSession.flushStatements(); sqlSession.commit(); sqlSession.clearCache(); } ``` 4. 在Service中调用Mapper接口中的批量插入或更新方法,传入需要插入或更新的数据集合即可: ``` @Autowired private UserMapper userMapper; @Transactional public void batchInsert(List<User> userList) { userMapper.batchInsert(userList); } @Transactional public void batchUpdate(List<User> userList) { userMapper.batchUpdate(userList); } ``` 总之,Mybatis-plus提供的批量插入更新操作非常简洁和高效,使用起来也比较方便,可以有效地提高开发效率。 ### 回答3: Mybatis-plus是一个基于Mybatis框架的增强工具,在Mybatis的基础上扩展并简化了一些操作,使得使用者可以更加便捷地进行数据库操作。Mybatis-plus提供了批量插入更新的功能,可以大大提高数据操作的效率和性能批量插入数据 使用Mybatis-plus进行批量插入数据的方法是使用mapper对象的batchInsert方法,示例如下: ```java List<User> userList = new ArrayList<>(); // 添加User对象到userList中 userService.batchInsert(userList); ``` 在上述示例代码中,我们将多个User对象添加到了userList中,然后调用userService的batchInsert方法进行批量插入。 批量更新数据 使用Mybatis-plus进行批量更新数据的方法是使用mapper对象的batchUpdate方法,示例如下: ```java List<User> userList = new ArrayList<>(); // 添加要更新的User对象到userList中 userService.batchUpdate(userList); ``` 在上述示例代码中,我们将多个要更新的User对象添加到了userList中,然后调用userService的batchUpdate方法进行批量更新。 需要注意的是,批量更新操作中要更新的字段必须相同,否则会更新失败。 总结 使用Mybatis-plus进行批量插入更新操作可以大大提高数据操作的效率和性能,但是需要注意,在批量更新操作中要更新的字段必须相同,否则会导致更新失败。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值