簡體   English   中英

使用foreach與mybatis進行批量插入

[英]using foreach to do batch insert with mybatis

我正在使用mybatis,我想將ArrayList插入到某個表中。
可以在mapper中使用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: 無效字符 
為了更新,我仍然需要幫助。 過來谷歌小組

在Mybatis中插入 foreach不是批處理 ,這是一個單獨的(可能變成巨大的)SQL語句,這帶來了一些缺點:

  • 某些數據庫如Oracle在這里不支持。
  • 在相關情況下:將插入大量記錄,並且將命中數據庫配置限制(默認情況下每個語句大約2000個參數),如果語句本身變得太大,最終可能會出現DB堆棧錯誤。

不能在mybatis XML中對集合進行迭代。 只需在Java Foreach循環中執行一個簡單的Insert語句。 最重要的是會話Executor類型

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

我認為在這里使用ExecutorType.REUSE而不刷新語句就足夠了。

與默認的ExecutorType.SIMPLE不同,語句將准備一次並為每個要插入的記錄執行。

嘗試提取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>

我認為您當前的代碼為每個元素創建了一個新的值角色,但是只有一個insert語句(這不是您想要的,您希望為每個元素插入一個)

Oracle不支持

插入xxx值(xxx,xxx),(xxx,xxx)

也許你可以像這樣使用insert

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM