web-dev-qa-db-ja.com

JdbcTemplateを使用して複数の行を挿入する

MySQLで JdbcTemplate を使用して、次のSQLをスケーラブルな方法で実行するにはどうすればよいですか。この場合、スケーラブルとは次のことを意味します。

  1. サーバー上で実行されるSQLステートメントは1つだけです
  2. 任意の数の行で機能します。

これがステートメントです:

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

fooおよびbarフィールドを持つPOJOのリストがあると仮定します。リストを反復処理して実行できることを理解しています。

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

しかし、それは最初の基準を達成しません。

私も実行できると思います:

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

しかし、私が知ることができることから、それはSQLを1回コンパイルして複数回実行し、最初の基準を再び失敗させます。

両方の基準を満たしているように見える最後の可能性は、StringBufferを使用して自分でSQLを構築することですが、それは避けたいと思います。

22
Edward Dale

複数行の挿入(「行値コンストラクター」を使用)は、実際にはSQL-92標準の一部です。 http://en.wikipedia.org/wiki/Insert_(SQL)#Multirow_inserts を参照してください。

一部のデータベースはこの構文をサポートしていませんが、多くはサポートしています。私の経験では、Derby/Cloudscape、DB2、Postgresql、および新しいHypersonic 2。* +リリースがこれをサポートしています。

これをPreparedStatementとして機能させることについてのあなたの懸念は理解できますが、Spring JDBCが特定のクエリのアイテムのコレクションを((?)のような)自動的に処理する同様のケースを見ましたが、このケースを保証することはできません。

(この投稿への2番目のリンクを追加することはできません)で、いくつかの助けになるかもしれない有用な情報を見つけました。

2番目の要件(任意の数の引数で機能)が最も厳密な意味で満たされることはおそらく不可能であることを私は言うことができます:私が使用したすべてのデータベースは、実行されるクエリの長​​さの制限を課します。

4
Will

以下のように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();
        }
    });

}
35
Desorder

この場合、JdbcTemplateのbatchUpdate()メソッドが役立つと思われます(ここからコピーします http://www.mkyong.com/spring/spring-jdbctemplate-batchupdate-example/ ):

//insert batch example
public void insertBatch(final List<Customer> customers){

  String sql = "INSERT INTO CUSTOMER " +
    "(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";

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

@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
    Customer customer = customers.get(i);
    ps.setLong(1, customer.getCustId());
    ps.setString(2, customer.getName());
    ps.setInt(3, customer.getAge() );
}

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

  });
 }
0