3

次の方法があります。コメントされたメソッド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;
    }
4

2 に答える 2

7

私は何が欠けていますか?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();
}

これにより、準備されたクエリが毎回置き換えられます。prepareStatement(...)バッチごとに 1 回だけ呼び出す必要があります。次のようなことをしているはずです。?引数を持つように挿入ステートメントを変更する必要があります。

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();

prepareStatement()1 つの呼び出しのみが使用されていることに注意してください。これには?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);
于 2012-05-19T10:14:02.920 に答える
-1

私が書いたコメントに加えて、私は答えを出す危険を冒します。次のようなことを試してみるとどうなりますか。

public boolean saveOrUpdate(MonitoredData mData) {
    try {
        PreparedStatement prep;
        String timeID = this.getTimeLastRowID();
        conn.setAutoCommit(false);
        for (CpuData o : mData.getCpu()) {
            prep = this.conn.prepareStatement(INSERT_CPU_USAGE);
            prep.setObject(1, this.nodeID);
            prep.setObject(2, timeID);
            prep.setObject(3, o);
            prep.addBatch();
            // saveOrUpdateToDatabase(String.format(INSERT_CPU_USAGE,
            // this.nodeID, timeID, o.toString()));
        }
        prep.executeBatch();
        for (DiskData o : mData.getDisk()) {
            prep = this.conn.prepareStatement(INSERT_DISK_USAGE);
            prep.setObject(1, this.nodeID);
            prep.setObject(2, timeID);
            prep.setObject(3, o);
            prep.addBatch();
            // saveOrUpdateToDatabase(String.format(INSERT_DISK_USAGE,
            // this.nodeID, timeID, o.toString()));
        }
        prep.executeBatch();
        for (NetworkData o : mData.getNet()) {
            prep = this.conn.prepareStatement(INSERT_NETWORK_USAGE);
            prep.setObject(1, this.nodeID);
            prep.setObject(2, timeID);
            prep.setObject(3, o);
            prep.addBatch();
            // saveOrUpdateToDatabase(String.format(INSERT_NETWORK_USAGE,
            // this.nodeID, timeID, o.toString()));

        }
        prep.executeBatch();
        prep = this.conn.prepareStatement(INSERT_MEMORY_USAGE);
        prep.setObject(1, this.nodeID);
        prep.setObject(2, timeID);
        prep.setObject(3, o);
        prep.executeUpdate();
        // saveOrUpdateToDatabase(String.format(INSERT_MEMORY_USAGE,
        // this.nodeID, timeID, mData.getMem().toString()));

        conn.setAutoCommit(true);
        return true;

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

定数で定義されている SQL クエリを変更する必要がある場合があります。

于 2012-05-18T22:45:20.483 に答える