Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java、MyBatis 3.4中,大量的批插入实际上并没有立即存储到数据库中_Java_Mysql_Mybatis - Fatal编程技术网

在Java、MyBatis 3.4中,大量的批插入实际上并没有立即存储到数据库中

在Java、MyBatis 3.4中,大量的批插入实际上并没有立即存储到数据库中,java,mysql,mybatis,Java,Mysql,Mybatis,任务:我需要一批至少插入10k条记录 事实上:在提交/刷新调用期间,我可以通过使用“SELECT*FROM TABLE”看到记录是以完全随机的数字插入的。 比如它可以插入1k,然后是500,再插入1.5k,然后再插入500。一些非常奇怪的事情正在发生 我有非常基本的设置,如: <bean id="armDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <propert

任务:我需要一批至少插入10k条记录

事实上:在提交/刷新调用期间,我可以通过使用“SELECT*FROM TABLE”看到记录是以完全随机的数字插入的。 比如它可以插入1k,然后是500,再插入1.5k,然后再插入500。一些非常奇怪的事情正在发生

我有非常基本的设置,如:

<bean id="armDataSource"
          class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbcUrl" value="${database.url}"/>
        <property name="user" value="${database.username}"/>
        <property name="password" value="${database.password}"/>
        <property name="maxPoolSize" value="30"/>
        <property name="idleConnectionTestPeriod" value="300"/>
        <property name="maxIdleTime" value="300"/>
        <property name="preferredTestQuery" value="SELECT 1"/>
        <property name="testConnectionOnCheckin" value="true"/>
    </bean>
    <tx:annotation-driven />

    <bean id="armTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="armDataSource"/>
    </bean>

    <bean id="armSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="armDataSource"/>
        <property name="typeAliasesPackage" value="com.database.arm.model"/>
    </bean>

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

然后我有以下代码:

SqlSession sqlSession = armSqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        HeaderMapper headerMapper = sqlSession.getMapper(HeaderMapper.class);
        List<List<HeaderDAO>> partitions = Lists.partition(HeaderDAOS, 10000);
                partitions.forEach(partition -> {
                    partition.forEach(headerDAO -> {
                        headerDAO.setFileId(fileId);
                        headerMapper.insert(headerDAO);
                    });
    sqlSession.flushStatements();
    });
        sqlSession.commit();
        sqlSession.close();
SqlSession SqlSession=armSqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);
HeaderMapper HeaderMapper=sqlSession.getMapper(HeaderMapper.class);
列表分区=列表分区(HeaderDAOS,10000);
partitions.forEach(分区->{
分区。forEach(headerDAO->{
headerDAO.setFileId(fileId);
封头上镶块(封头道);
});
sqlSession.flushStatements();
});
提交();
sqlSession.close();
它只适用于100条或更少记录的小批量插入。但一旦我走得更高,看起来Mybati做的比一批还要多

sqlSessionFactory或模板或数据源的设置可能有问题?我尝试了很多选择,但都没用。
非常感谢您的任何输入。

因此我调试了所有的堆栈直到mysql驱动程序,并找到了原因。 默认情况下,MySQL驱动程序实际上在一个事务中逐个执行批插入。 要启用一个大批量插入,需要使用以下属性让mysqldriver知道:

rewriteBatchedStatements=true

这可以在数据源的connectionUrl中绕过,或通过数据源的属性指定:

<property name="properties">
    <props>
        <prop key="rewriteBatchedStatements">true</prop>
    </props>
</property>

真的

注意:您只需要在MyBatis的情况下使用它,因为例如Hibernate将自动执行此操作。

因此我已经调试了所有堆栈直到mysql驱动程序,并找到了原因。 默认情况下,MySQL驱动程序实际上在一个事务中逐个执行批插入。 要启用一个大批量插入,需要使用以下属性让mysqldriver知道:

rewriteBatchedStatements=true

这可以在数据源的connectionUrl中绕过,或通过数据源的属性指定:

<property name="properties">
    <props>
        <prop key="rewriteBatchedStatements">true</prop>
    </props>
</property>

真的
注意:您只需要在MyBatis的情况下使用它,因为例如Hibernate会自动执行