2

所以我有一个软件,它基本上从我的 MySQL db 下载 1.5K 游戏服务器地址。然后它会ping所有这些,然后将在线玩家等信息上传回数据库。该过程如下所示:

  1. 下载服务器地址
  2. ping 服务器并获取信息
  3. 将信息上传回数据库

到目前为止,我已经能够解决下载服务器主机名并 ping 它们的部分,但是在更新服务器时会出现问题。

为了更新,我考虑过使用 for 循环来构造一个包含许多更新语句的大字符串并立即执行它,但这很容易发生 sql 注入。因此,理想情况下,人们会想要使用准备好的语句。

我正在使用的 SQL 更新语句是:

UPDATE serverlist SET `onlineplayers` = '3', maxplayers = '10', 
name = 'A game server' WHERE `ip` = 'xxx.xxx.xxx.xxx' AND `port` = 1234;

所以我的问题是:
如何使用参数化查询执行所有 1.5K 更新语句?

4

4 回答 4

4

如果你用谷歌搜索“jdbc 批量更新”,你会得到很多类似 thisthis的结果。

后者有一个这样的例子:

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
} 
于 2013-02-01T17:01:49.940 回答
3

听起来您想要进行批量 SQL 更新。准备好的陈述是你的朋友。下面是一个批量使用准备好的语句的例子:

http://www.mkyong.com/jdbc/jdbc-preparedstatement-example-batch-update/

使用准备好的语句使设置参数更容易,它允许数据库有效地执行多次更新。执行多个 SQL 字符串会起作用,但效率会很低,因为每个 SQL 字符串都将被发送到 DBMS、解析、编译,然后执行。使用准备好的语句,SQL 会被解析和编译一次,然后重新用于具有不同参数的未来更新。

于 2013-02-01T16:59:33.270 回答
3

在 MySQL 批量更新/插入期间您应该注意的另一个重要步骤是 JDBC 连接属性rewriteBatchedStatements=true(默认为 false )。没有它批处理模式是无用的。在我发现这一点之前,我花了 1 天的时间来“修复错误”。当您的行数较少并关闭客户端到数据库的位置(1ms ping)时,您甚至无法意识到您处于“假批处理模式”,但是当我将环境切换到远程客户端(ping=100ms)和 100k要更新的行,默认rewriteBatchedStatements=false需要 4 小时的“批量模式更新”,而 rewriteBatchedStatements=true只需2 分钟

于 2016-10-28T15:37:43.550 回答
1

创建一个准备好的语句:

String sql = "update serverlist SET onlineplayers = ?, maxplayers = ?, name = ? where ip = ? and port = ?";
PreparedStatement stmt = connection.prepareStatement(sql);

然后遍历您的列表,并在每次迭代时执行

stmt.setInt(1, onlinePlayers);
stmt.setInt(2, maxPlayers);
stmt.setString(3, name);
stmt.setString(4, ip);
stmt.setInt(5, port);
stmt.executeUpdate();

为了获得更好的性能,您还可以使用批量更新。

阅读JDBC 教程

于 2013-02-01T17:02:51.087 回答