SQLite中的Java PreparedStatement.executeBatch()不起作用

Ped*_*sso 2 java sqlite prepared-statement

我有以下方法.注释方法saveOrUpdateToDatabase执行完全正常,但我想使用executeBatch.我错过了什么?接收executeBatch()结果的int [] r总是空的...

public boolean saveOrUpdate(MonitoredData mData) {
        try {
            PreparedStatement prep;
            String timeID = this.getTimeLastRowID();

            for (CpuData o : mData.getCpu()) {
                prep = this.conn.prepareStatement(String.format(
                        INSERT_CPU_USAGE, this.nodeID, timeID, o.toString()));
                prep.addBatch();
                // saveOrUpdateToDatabase(String.format(INSERT_CPU_USAGE,
                // this.nodeID, timeID, o.toString()));
            }
            for (DiskData o : mData.getDisk()) {
                prep = this.conn.prepareStatement(String.format(
                        INSERT_DISK_USAGE, this.nodeID, timeID, o.toString()));
                prep.addBatch();
                // saveOrUpdateToDatabase(String.format(INSERT_DISK_USAGE,
                // this.nodeID, timeID, o.toString()));

            }
            for (NetworkData o : mData.getNet()) {
                prep = this.conn.prepareStatement(String
                        .format(INSERT_NETWORK_USAGE, this.nodeID, timeID, o
                                .toString()));
                prep.addBatch();
                // saveOrUpdateToDatabase(String.format(INSERT_NETWORK_USAGE,
                // this.nodeID, timeID, o.toString()));

            }

            prep = this.conn.prepareStatement(String.format(
                    INSERT_MEMORY_USAGE, this.nodeID, timeID, mData.getMem()
                            .toString()));
            // saveOrUpdateToDatabase(String.format(INSERT_MEMORY_USAGE,
            // this.nodeID, timeID, mData.getMem().toString()));

            conn.setAutoCommit(false);
            int[] r = prep.executeBatch();
            conn.setAutoCommit(true);

            return true;

        } catch (SQLException ex) {
            Logger.getLogger(HistoricalDatabase.class.getName()).log(
                    Level.SEVERE, null, ex);
        }
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

Gra*_*ray 6

我错过了什么?接收executeBatch()结果的int [] r总是空的...

您使用的addBatch()方法不正确.在你的代码中你正在做:

for (CpuData o : mData.getCpu()) {
    // this is wrong, you can not prepare a new query each time
    prep = this.conn.prepareStatement(INSERT_CPU_USAGE);
    prep.setObject(1, this.nodeID);
    prep.addBatch();
}
Run Code Online (Sandbox Code Playgroud)

这每次都会替换准备好的查询.你应该prepareStatement(...)每批只调用一次.你应该做类似以下的事情.您必须将insert语句更改为具有?参数:

PreparedStatement prep = conn.prepareStatement(INSERT_CPU_USAGE);
for (CpuData o : mData.getCpu()) {
    prep.setObject(1, this.nodeID);
    prep.setObject(2, timeID);
    prep.setObject(3, o);
    prep.addBatch();
}
prep.executeBatch();
Run Code Online (Sandbox Code Playgroud)

请注意,只使用了一个prepareStatement()呼叫.这里面有?SQL参数实体,然后在循环中分配prep.setString(1, ...).当该批次已准备好执行你打电话prep.executeBatch(),但是这是没有过更换prep你正在做准备好的声明.

如果您尝试在同一批次中连续执行一系列不同的插入语句,那么您应该考虑关闭自动提交,执行语句,调用提交,然后重新打开自动提交.就像是:

conn.setAutoCommit(false);
// statements prepared and executed here
// maybe no need for batch operations
...
conn.commit();
conn.setAutoCommit(true);
Run Code Online (Sandbox Code Playgroud)