如果我有一个使用以下架构创建的表:
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
比仅仅构造查询字符串并直接执行它更理想吗?
答案 0 :(得分:2)
还有两个选项:
使用PreparedStatement.addBatch()
。对于许多数据库,这将减少服务器往返次数。但不适用于所有数据库(例如,不适用于H2数据库)。
使用PreparedStatement
,但批量使用多行:
INSERT INTO names (name) VALUES (?), (?), (?), (?), (?), (?), (?), (?);
第二个应该减少所有数据库的服务器往返,但它有点复杂。
答案 1 :(得分:0)
是的更快 因为每次java应用程序向数据库发送新的SQL语句时,服务器都会检查语法错误,准备执行语句的计划并执行它。
如果再次发送相同的语句,尽管数据库服务器会检查它是否已经收到完全相同的语句。如果是这样,服务器不检查其语法并为其准备执行计划,以便服务器只执行它。
为了利用这个数据库功能,java提供了使用预准备语句。此功能允许您通过接受发送给它的参数值,将send语句发送到重复执行的数据库服务器。这改进了数据库性能,因为数据库服务器只需检查语法并为每个语句准备一次执行计划。