mybatis的三種批量插入以及次效率比較


 正文前先來一波福利推薦:

 福利一:

百萬年薪架構師視頻,該視頻可以學到很多東西,是本人花錢買的VIP課程,學習消化了一年,為了支持一下女朋友公眾號也方便大家學習,共享給大家。

福利二:

畢業答辯以及工作上各種答辯,平時積累了不少精品PPT,現在共享給大家,大大小小加起來有幾千套,總有適合你的一款,很多是網上是下載不到。

獲取方式:

微信關注 精品3分鍾 ,id為 jingpin3mins,關注后回復   百萬年薪架構師 ,精品收藏PPT  獲取雲盤鏈接,謝謝大家支持!

-----------------------正文開始---------------------------

 

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

 

結果對比:

  第一種 第二種 第三種
500條 7742 7388 622
1000條 15290 15078 746
5000條 78011 177350 1172
10000條 397472 201180 1205


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM