java - mybatis使用foreach进行批量插入

标签 java oracle mybatis

我正在使用 mybatis,我想将 ArrayList 插入到某个表中。
好吧,在映射器中使用 foreach ,这最终会导致 Oracle 异常 ORA_00933 。
这是 mybatis 映射器:

<insert id="batchInsert" parameterType="java.util.List">
		insert into SYS_ROLES_PERMISSIONGROUP
		(role_id, permissiongroup_id)
		values
		<foreach collection="list" item="model" index="index" separator=","> 
        (#{model.role_id}, #{model.permissiongroup_id})
    	</foreach>
	</insert>

org.springframework.jdbc.BadSqlGrammarException: 
### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束

### The error may involve com.gaotime.platform.system.mapper.RolePermissiongroupMapper.batchInsert-Inline
### The error occurred while setting parameters
### SQL: insert into SYS_ROLES_PERMISSIONGROUP   (role_id, permissiongroup_id)   values               (?, ?)      ,           (?, ?)      ,           (?, ?)
### Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束

; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束

	at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:95)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:364)
	at com.sun.proxy.$Proxy5.insert(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:236)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:51)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
	at com.sun.proxy.$Proxy15.batchInsert(Unknown Source)
	at com.gaotime.platform.system.service.RolePermissiongroupService.batchInsert(RolePermissiongroupService.java:18)
	at com.gaotime.platform.system.action.RolePermissiongroupAction.execute(RolePermissiongroupAction.java:54)
	at com.gaotime.platform.handler.MqMessageHandler.handle(MqMessageHandler.java:20)
	at unitask.ums.activemq.HandlerThread.run(HandlerThread.java:51)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束

	at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
	at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395)
	at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802)
	at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
	at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
	at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521)
	at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:205)
	at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1008)
	at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
	at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3449)
	at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3550)
	at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1374)
	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.execute(NewProxyPreparedStatement.java:989)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:62)
	at com.sun.proxy.$Proxy27.execute(Unknown Source)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:44)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:69)
	at org.apache.ibatis.executor.ReuseExecutor.doUpdate(ReuseExecutor.java:50)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:105)
	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:71)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:152)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:141)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:354)
请大家帮帮我,谢谢

另一个映射器配置

<insert id="batchInsert" parameterType="java.util.List">
	    <foreach collection="list" item="model" index="index" separator=","> 
		insert into SYS_ROLES_PERMISSIONGROUP
		(role_id, permissiongroup_id)
		values
		
        (#{model.role_id}, #{model.permissiongroup_id})
    	</foreach>
	</insert>
我收到这条消息

org.springframework.jdbc.BadSqlGrammarException: 
### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束

### The error may involve com.gaotime.platform.system.mapper.RolePermissiongroupMapper.batchInsert-Inline
### The error occurred while setting parameters
### SQL: insert into SYS_ROLES_PERMISSIONGROUP   (role_id, permissiongroup_id)   values            (?, ?)       ,     insert into SYS_ROLES_PERMISSIONGROUP   (role_id, permissiongroup_id)   values            (?, ?)       ,     insert into SYS_ROLES_PERMISSIONGROUP   (role_id, permissiongroup_id)   values            (?, ?)
### Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束

; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束
这是静态插入语句

<insert id="batchInsert" parameterType="java.util.List">
	    <!-- <foreach collection="list" item="model" index="index" separator=";"> 
		insert into SYS_ROLES_PERMISSIONGROUP
		(role_id, permissiongroup_id)
		values
		
        (#{model.role_id,jdbcType=NUMERIC}, #{model.permissiongroup_id,jdbcType=NUMERIC})
    	</foreach> -->
    	insert into SYS_ROLES_PERMISSIONGROUP
		(role_id, permissiongroup_id)
		values(5,5);
		insert into SYS_ROLES_PERMISSIONGROUP
		(role_id, permissiongroup_id)
		values(6,6)
	</insert>
和异常

19:00:21,531 DEBUG Thread-11 RolePermissiongroupMapper.batchInsert:139 - ==>  Preparing: insert into SYS_ROLES_PERMISSIONGROUP (role_id, permissiongroup_id) values(5,5); insert into SYS_ROLES_PERMISSIONGROUP (role_id, permissiongroup_id) values(6,6) 
19:00:21,535 DEBUG Thread-11 RolePermissiongroupMapper.batchInsert:139 - ==> Parameters: 
19:00:21,553 DEBUG Thread-11 impl.NewPooledConnection:430 - com.mchange.v2.c3p0.impl.NewPooledConnection@699238ad handling a throwable.
java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
对于更新,我仍然需要帮助。过来google group

最佳答案

Insert在Mybatis中foreach不是批处理,这是一个单一的(可能会变成巨大的)SQL语句,并且带来了缺点:

  • 这里不支持某些数据库,例如Oracle。
  • 在相关情况下:将需要插入大量记录,并且将达到数据库配置的限制(默认情况下每个语句大约 2000 个参数),如果语句本身变得太大,最终可能会出现数据库堆栈错误。

不得在 mybatis XML 中对集合进行迭代。 只需在 Java Foreach 循环中执行一个简单的 Insert 语句即可。 最重要的是 session 执行器类型

SqlSession session = sessionFactory.openSession(ExecutorType.BATCH);
for (Model model : list) {
    session.insert("insertStatement", model);
}
session.flushStatements();

我认为这里使用 ExecutorType.REUSE 就足够了,无需刷新语句。

与默认的 ExecutorType.SIMPLE 不同,该语句将准备一次并针对要插入的每条记录执行。

关于java - mybatis使用foreach进行批量插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32649759/

相关文章:

sql-server - 为什么我在 Oracle DATE 列中看到值 '2432-82-75 50:08:01'?

java - 如何在 ResponseEntity 中不返回空值?

java - MyBatis - 在 foreach 中绑定(bind)参数

java - Mybatis,封闭 OR 与 SQL 构建器

java - 为什么我无法将项目添加到另一个 FXML 中的表中?

java - “\n” 使用 BufferWriter 将字符串保存到文本文件时不添加新行

java - 如何使用jdbcTemplate在多行条件查询中设置参数

java - 托盘图标显示不正确

sql - 选择最近但不大于行

mysql - varchar2 和 number 数据类型导致 phpmyadmin 中的 SQL 查询编辑器出现错误