【问题标题】:using JDBC preparedStatement in a batch批量使用 JDBCpreparedStatement
【发布时间】:2011-10-15 04:45:32
【问题描述】:

我正在使用Statements 批量查询我的数据库。 我现在做了一些研究,我想重写我的应用程序以改用preparedStatement,但我很难弄清楚如何将查询添加到preparedStatement 批处理。

这就是我现在正在做的:

private void addToBatch(String sql) throws SQLException{
sttmnt.addBatch(sql);
batchSize++;
if (batchSize == elementsPerExecute){
    executeBatches();
}
}

其中sttmntStatement 类型的类成员。

我要做的是使用preparedStatementsetString(int, String)方法设置一些动态数据,然后添加到批处理中。

不幸的是,我不完全了解它是如何工作的,以及如何将setString(int, String) 用于批处理中的特定 sql,或者为我拥有的每个 sql 创建一个新的preparedStatemnt,然后将它们全部加入一个批处理.

可以这样做吗?还是我对preparedStatement 的理解真的遗漏了什么?

【问题讨论】:

  • 如果您找到了答案,请接受对您有所帮助的答案,以便其他人也可以学习

标签: java jdbc batch-file prepared-statement


【解决方案1】:

阅读section 6.1.2 of this document 获取示例。基本上,您使用相同的语句对象并在设置所有占位符后调用批处理方法。 Another IBM DB2 example 应该适用于任何 JDBC 实现。从第二个站点:

try {
  connection con.setAutoCommit(false);        
  PreparedStatement prepStmt = con.prepareStatement(    
    "UPDATE DEPT SET MGRNO=? WHERE DEPTNO=?");
  prepStmt.setString(1,mgrnum1);            
  prepStmt.setString(2,deptnum1);
  prepStmt.addBatch();                      

  prepStmt.setString(1,mgrnum2);                        
  prepStmt.setString(2,deptnum2);
  prepStmt.addBatch();
  int [] numUpdates=prepStmt.executeBatch();
  for (int i=0; i < numUpdates.length; i++) {
    if (numUpdates[i] == -2)
      System.out.println("Execution " + i + 
        ": unknown number of rows updated");
    else
      System.out.println("Execution " + i + 
        "successful: " + numUpdates[i] + " rows updated");
  }
  con.commit();
} catch(BatchUpdateException b) {
  // process BatchUpdateException
} 

【讨论】:

  • 但是如果我想让语句不同怎么办,比如说一个 INSERT,然后是几个更新?我可以这样做吗?
  • AFAIK,没有。如您所见,addBatch 是在 Statement 对象上调用的,因此持有的任何语句都将添加到批处理中。如果您有多种类型的语句,则不再是批处理;它有点变成了一个脚本。
  • Statement 有一个方法void addBatch(String sql) 允许组装批次(这可能被视为脚本)
【解决方案2】:

对于PreparedStatement,您在某种程度上拥有通配符,例如

Sring query = "INSERT INTO users (id, user_name, password) VALUES(?,?,?)";
PreparedStatement statement = connection.preparedStatement(query);
for(User user: userList){
    statement.setString(1, user.getId()); //1 is the first ? (1 based counting)
    statement.setString(2, user.getUserName());
    statement.setString(3, user.getPassword()); 
    statement.addBatch();
}

这将使用上面显示的查询创建 1 个PreparedStatement。当您想要插入或任何您的意图时,您可以循环遍历列表。当你想处决你时,

statement.executeBatch();
statement.clearBatch(); //If you want to add more, 
//(so you don't do the same thing twice)

【讨论】:

    【解决方案3】:

    我在这里专门为 MySQL 添加一个额外的答案。

    我发现执行一批插入的时间与执行单个插入的时间长度相似,即使是围绕批处理的单个事务也是如此。

    我将参数 rewriteBatchedStatements=true 添加到我的 jdbc url,并看到了显着的改进 - 在我的例子中,一批 200 个插入从 125 毫秒开始。没有参数到大约 10 到 15 毫秒。带参数。

    MySQL and JDBC with rewriteBatchedStatements=true

    【讨论】:

      猜你喜欢
      • 2020-07-04
      • 1970-01-01
      • 2015-12-20
      • 2015-03-30
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      相关资源
      最近更新 更多