db = new Database(dbURL, false);   
    conn = db.getConn();   
    pstmt = conn.prepareStatement(preSql);   
       
    conn.setAutoCommit(false);   
    for (int j = 0; j < commitCount; ++j) {   
        try {   
            pstmt.clearBatch();   
            pstmt.clearParameters();   
            String[] tmp = ((String[])setConf.elementAt(j));   
            for (int i = 1; i <= tmp.length; ++i) {   
                pstmt.setString(i, tmp[i - 1]);   
            }   
            pstmt.addBatch();   
        } catch (SQLException e) {   
            Loger.log.error("some operation about pstmt throw SQLException!\n" + e);   
            continue;   
        }   
    }   
    tmpRets = pstmt.executeBatch();   
    conn.commit();  我用上面的代码执行批量的插入,只执行一次executeBatch操作,但每次只能插入第一条数据,所以更通的办法是在for里面执行这个操作,这样就是一条数据就提交一次了,效率肯定低。但我不知道为什么会这样。我看网上很多类似代码也是这样的逻辑的啊。另外,如果我不需要事务,我能否不要setAutoCommit,这样好像又不是一次提交是吗?而是每次都提交吗?

解决方案 »

  1.   

    我把pstmt.clearBatch()放在for前面去了,可执行后出现: 
    java.sql.SQLException: System or internal error java.lang.ArrayIndexOutOfBoundsException: 22 >= 22
    的异常,我的prepared sql是一上需要设置11列的语句,所以是在for中第二次设置时出了错,我不知道为什么会有这样的问题,我也做了pstmt.clearParameters(); 操作啊。
      

  2.   

    为什么要调用clearBatch()?JDK DOC对这个方法的描述:
    Empties this Statement object's current list of SQL commands. 
    从这句话来看,岂不是整个SQL命令的列表都被清空了?另外如果没有必要clearParameters()也无需调用。
    DOC的说法是:
    However, in some cases it is useful to immediately release the resources used by the current parameter values除非你有必要即时释放当前参数占用的资源,否则没必要调用该方法。
      

  3.   

    另外,为了保证数据的完整性,
    conn.setAutoCommit(false);是必须的。如果一个业务要求一次变更多条记录,
    但是如果没有完全更新操作就中止了,
    那么显然不符合业务要求。
      

  4.   

    to wingtrace:
    我前面说了,“我把pstmt.clearBatch()放在for前面去了”。所以不存在清除了batch的问题。因为每个batch都需要设置一些参数,所以在设置之前进行clearParameters我觉得应该是没有问题的。我调试了一下发现,我要设置的参数是11个,在循环两次后都没有问题,第三次时设置第一个参数就会抛出下面的异常System or internal error java.lang.ArrayIndexOutOfBoundsException: 22 >= 22
    如果我要设置的参数是10个的话,在循环两次后还是没问题,第三次时设置第一个参数就会出现类似的异常信息:
    System or internal error java.lang.ArrayIndexOutOfBoundsException: 20 >= 20我就想为什么总是在第三个batch里的第一次设置参数就出异常呢?很是不明白。
      

  5.   

    另外,为了保证数据的完整性,
    conn.setAutoCommit(false);是必须的。如果一个业务要求一次变更多条记录,
    但是如果没有完全更新操作就中止了,
    那么显然不符合业务要求。
    =================================
    to wingtrace:
     
    我不需要保证数据的完整性,只是插入一些数据而已,插不进去也不需要保证一个事务。
    所以我到底需不需要设置成false呢?如果不设置成false能否进行一次性提交操作呢?
      

  6.   

    to william3033():
    不要没看完问题就在那说数组越界,抛出 ArrayIndexOutOfBoundsException 当然是数组越界的意思,但我调试后的现象我也说了,希望你也看看清楚。
      

  7.   

    我不需要保证数据的完整性,只是插入一些数据而已,插不进去也不需要保证一个事务。
    所以我到底需不需要设置成false呢?如果不设置成false能否进行一次性提交操作呢?
    ============================================================================
    如果不需要事务支持,那么设置为true(缺省)即可。
    批处理的成败跟自动提交没有必然关系。看起来你现在的问题不在于prepareStatement的批处理,
    而是在于集合操作。把详细一点的错误报告贴出来看看吧。
      

  8.   

    pstmt.clearBatch();
    pstmt.clearParameters(); 放到for外面或者就不用加还有请数一下你的问号,是不是和你的数组长度一样