Используя foreach, чтобы сделать пакетную вставку с mybatis

Я использую mybatis, и я хотел бы вставить ArrayList в какую-то таблицу.
все в порядке с использованием foreach в mapper, что в итоге приводит к исключению оракула 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

3 ответа

Решение

Вставка внутри Mybatis foreach - это не пакетная обработка, это единственный (может стать гигантским) оператор SQL, который имеет недостатки:

  • некоторые базы данных, такие как Oracle, здесь не поддерживаются.
  • в соответствующих случаях: будет вставлено большое количество записей, и будет достигнут сконфигурированный лимит базы данных (по умолчанию около 2000 параметров на оператор), и в конечном итоге возможно ошибка стека БД, если сам оператор станет слишком большим.

Итерации по коллекции не должны выполняться в mybatis XML. Просто выполните простую инструкцию Insert в цикле Java Foreach.Самым важным является тип сеанса Executor.

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

Я думаю, что здесь будет достаточно использовать ExecutorType.REUSE без операторов очистки.

В отличие от ExecutorType.SIMPLE по умолчанию, инструкция будет подготовлена ​​один раз и выполнена для каждой записи для вставки.

Oracle не поддерживает

вставить в ххх значения (ххх, ххх),(ххх, ххх)

может быть, вы можете использовать вставить все, как это

    <insert id="batchInsert">
    INSERT ALL
    <foreach collection="list" item="model">
        INTO
        SYS_ROLES_PERMISSIONGROUP (role_id, permissiongroup_id)
        VALUES
        (#{model.role_id}, #{model.permissiongroup_id})
    </foreach>
   </insert>

Попробуйте извлечь foreach (и измените разделитель):

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

Я думаю, что ваш текущий код создает новую роль значений для каждого элемента, но один оператор вставки (это не то, что вы хотите, вы хотите вставку для каждого элемента)

Другие вопросы по тегам