mybatis三种批量插入方式对比

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.配置

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>

<!-- spring与mybatis整合类 -->

<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. 

 

结果对比:

时间有限测试数据较少,有兴趣可以自己测试以下。(不清楚为什么BATCH有时候比单条循环插入还耗时间,请知道的大神不吝赐教,感谢!)

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答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进行批量插入更新操作可以大大提高数据操作的效率和性能,但是需要注意,在批量更新操作中要更新的字段必须相同,否则会导致更新失败。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值