多行INSERT与重复调用PreparedStatement.executeUpdate()

时间:2013-08-01 04:07:13

标签: java sql jdbc prepared-statement

如果我有一个使用以下架构创建的表:

CREATE TABLE names (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR);

我要添加到表中的List<String> names个名称,我看到了两种方法。

简单,强力的解决方案是手动构建SQL,如下所示:

String sql = "INSERT INTO names (name) VALUES ("+
             Joiner.on("), (").join(names)+
             ");";
conn.createStatement().execute(sql);

这恰好击中了数据库一次,看起来直观而且直截了当。我知道存在SQL注入问题,但是为了这个问题,让我们假设已经解决了这些问题。

替代方法是使用预准备语句,并JDBC docs suggest重复执行该语句,如下所示:

con.setAutoCommit(false);
PreparedStatement addNames = con.prepareStatement(
   "INSERT INTO names (name) VALUES (?);");

for (String name : names) {
    addNames.setString(1, name);
    addNames.executeUpdate();
    con.commit();
}
con.setAutoCommit(true);

真的是这样反复执行PreparedStatement比仅仅构造查询字符串并直接执行它更理想吗?

2 个答案:

答案 0 :(得分:2)

还有两个选项:

  • 使用PreparedStatement.addBatch()。对于许多数据库,这将减少服务器往返次数。但不适用于所有数据库(例如,不适用于H2数据库)。

  • 使用PreparedStatement,但批量使用多行:

    INSERT INTO names (name) VALUES (?), (?), (?), (?), (?), (?), (?), (?);
    

第二个应该减少所有数据库的服务器往返,但它有点复杂。

答案 1 :(得分:0)

是的更快 因为每次java应用程序向数据库发送新的SQL语句时,服务器都会检查语法错误,准备执行语句的计划并执行它。

如果再次发送相同的语句,尽管数据库服务器会检查它是否已经收到完全相同的语句。如果是这样,服务器不检查其语法并为其准备执行计划,以便服务器只执行它。

为了利用这个数据库功能,java提供了使用预准备语句。此功能允许您通过接受发送给它的参数值,将send语句发送到重复执行的数据库服务器。这改进了数据库性能,因为数据库服务器只需检查语法并为每个语句准备一次执行计划。