2

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

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 文档建议重复执行该语句,如下所示:

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);

像这样重复执行 a 真的PreparedStatement比简单地构造查询字符串并直接执行更可取吗?

4

2 回答 2

2

还有两个选择:

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

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

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

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

于 2013-09-27T17:40:52.967 回答
0

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

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

为了利用这个数据库特性,java 提供了使用prepared statement。这个特性允许你发送send statements 到数据库服务器,通过接受发送给它的参数值来重复执行。这提高了数据库性能,因为数据库服务器只需检查语法并为每条语句准备一次执行计划。

于 2013-08-01T04:18:49.833 回答