使用 JdbcTemplate 插入多行

2022-09-01 18:42:04

如何使用在mySQL上运行的JdbcTemplate以可扩展的方式执行以下SQL。在这种情况下,可扩展意味着:

  1. 服务器上只执行一个 SQL 语句
  2. 它适用于任意数量的行。

声明如下:

INSERT INTO myTable (foo, bar) VALUES ("asdf", "asdf"), ("qwer", "qwer")

假设我有一个POJO的带有和字段的列表。我意识到我可以只是迭代列表并执行:foobar

jdbcTemplate.update("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMap)

但这并不能完成第一个标准。

我相信我也可以执行:

jdbcTemplate.batchUpdate("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMapArray)

但据我所知,这将只是编译SQL一次并多次执行它,再次不符合第一个标准。

最后一种可能性,似乎同时通过了这两个标准,就是简单地用 一个 来构建SQL,但我想避免这种情况。StringBuffer


答案 1

您可以使用 BatchPreparedStatementSetter,如下所示。

public void insertListOfPojos(final List<MyPojo> myPojoList) {

    String sql = "INSERT INTO "
        + "MY_TABLE "
        + "(FIELD_1,FIELD_2,FIELD_3) "
        + "VALUES " + "(?,?,?)";

    getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {

        @Override
        public void setValues(PreparedStatement ps, int i)
            throws SQLException {

            MyPojo myPojo = myPojoList.get(i);
            ps.setString(1, myPojo.getField1());
            ps.setString(2, myPojo.getField2());
            ps.setString(3, myPojo.getField3());

        }

        @Override
        public int getBatchSize() {
            return myPojoList.size();
        }
    });

}

答案 2

多行插入(使用“行值构造函数”)实际上是 SQL-92 标准的一部分。请参见 http://en.wikipedia.org/wiki/Insert_(SQL)#Multirow_inserts

某些数据库不支持此语法,但许多数据库支持此语法。根据我的经验,Derby/Cloudscape,DB2,Postgresql和较新的Hypersonic 2.*+版本确实支持这一点。

你对让它作为PredentStatement工作的担忧是可以理解的,但是我见过类似的情况,其中Spring JDBC确实自动处理某些查询的项目集合(例如(?)中的位置),但我无法保证这种情况。

我确实在(无法添加第二个链接到这篇文章)上找到了一些可能有用的信息,这可能会有所帮助。

我可以告诉你,你的第二个要求(适用于任何数量的参数)可能不可能在最严格的意义上得到满足:我使用过的每个数据库都确实施加了查询长度限制,这些限制会发挥作用。


推荐