25

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

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

ステートメントは次のとおりです。

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

fooPOJOのwithフィールドとフィールドのリストがあると仮定しbarます。リストを繰り返して実行できることに気づきました。

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

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

私も実行できると信じています:

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

しかし、私が言えることから、それはSQLを1回コンパイルし、それを複数回実行するだけで、最初の基準に再び失敗します。

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

4

5 に答える 5

43

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

}
于 2012-01-15T21:32:37.620 に答える
5

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

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

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

私はいくつかの役立つかもしれないいくつかのおそらく役立つ情報を見つけました(この投稿に2番目のリンクを追加することはできません)。

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

于 2010-10-15T18:41:06.390 に答える
4

この場合、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();
}

  });
 }
于 2015-07-27T11:20:18.273 に答える
-1

jdbcInsert.executeBatch(sqlParamSourceArray)で試すこともできます

   // define parameters
jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("TABlE_NAME");
SqlParameterSource[] sqlParamSourceArray = new SqlParameterSource[apiConsumer
        .getApiRoleIds().size()];
for (int i = 0; i < myCollection.size(); i++) 
    {
  sqlParamSourceArray[i] = new MapSqlParameterSource().addValue("COL1");
      ......................
}
// execute insert
int[] keys = jdbcInsert.executeBatch(sqlParamSourceArray);
于 2014-02-07T09:40:22.690 に答える
-4

JDBC、期間ではこれを行うことはできません。MySQLでは、これは単なる構文糖衣ですが、ステートメントの効果は、いくつかのINSERTステートメントを発行するのと同じになります。したがって、batchUpdateを使用すると、同じ効果が得られます。

于 2010-10-14T18:09:50.033 に答える