所以我有一个软件,基本上从我的MySQL数据库下载1.5K游戏服务器地址。然后它会ping所有这些内容,然后将在线播放器等信息上传回数据库。这个过程如下:
到目前为止,我已经能够解决下载服务器主机名的部分并对它们进行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更新语句?
答案 0 :(得分:3)
听起来您想要进行批量SQL更新。准备好的陈述是你的朋友。以下是批量使用预准备语句的示例:
http://www.mkyong.com/jdbc/jdbc-preparedstatement-example-batch-update/
使用预准备语句可以更轻松地设置参数,并允许DB有效地执行多个更新。执行多个SQL字符串会起作用,但效率很低,因为每个SQL字符串都会被发送到DBMS,解析,编译,然后执行。使用预准备语句,SQL将被解析和编译一次,然后重用于具有不同参数的未来更新。
答案 1 :(得分:3)
如果你谷歌搜索“jdbc批量更新”,你会得到很多结果like this one或this one。
后者有一个这样的例子:
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
}
答案 2 :(得分:3)
在MySQL批量更新/插入期间,您应该注意的另一个重要步骤是JDBC连接属性 rewriteBatchedStatements = true (默认为false)。没有它批处理模式是没用的。 花了我1天的时间来修复bug&#34;直到我发现了这个。 当您拥有少量线路并关闭客户端到数据库的位置(1毫秒ping)时,您甚至无法意识到您处于&#34;假批处理模式&#34; ,但是当我将环境切换到远程客户端(ping = 100ms)和100k行进行更新时,需要4小时的批量模式更新&#34;默认 rewriteBatchedStatements = false ,只需2分钟 rewriteBatchedStatements = true
答案 3 :(得分: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();
为了获得更好的性能,您还可以使用批量更新。