我有以下方法。注释的方法保存或更新到数据库执行得很好,但我想使用 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;
}
我错过了什么?接收 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(...)
一次。 您应该执行以下操作。 您必须更改插入语句以包含?
参数:
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()
调用。 这其中有?
个 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);
除了我写的评论,我冒着给出答案的风险。如果您尝试这样的事情怎么办:
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 查询。