java – MySql中的Multipile更新语句

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

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

到目前为止,我已经能够解决下载服务器主机名的部分并对其进行ping操作,但更新服务器时出现问题。

要更新我想过使用for循环来构造一个包含许多更新语句的BIG字符串并立即执行它,但这很容易进行sql注入。 因此,想要使用准备好的语句。

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

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

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

如果你谷歌搜索“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 } 

听起来你想要进行批量SQL更新。 准备好的陈述是你的朋友。 以下是批量使用预准备语句的示例:

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

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

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

创建准备好的声明:

 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教程 。