MySQLで JdbcTemplate を使用して、次のSQLをスケーラブルな方法で実行するにはどうすればよいですか。この場合、スケーラブルとは次のことを意味します。
これがステートメントです:
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を構築することですが、それは避けたいと思います。
複数行の挿入(「行値コンストラクター」を使用)は、実際にはSQL-92標準の一部です。 http://en.wikipedia.org/wiki/Insert_(SQL)#Multirow_inserts を参照してください。
一部のデータベースはこの構文をサポートしていませんが、多くはサポートしています。私の経験では、Derby/Cloudscape、DB2、Postgresql、および新しいHypersonic 2。* +リリースがこれをサポートしています。
これをPreparedStatementとして機能させることについてのあなたの懸念は理解できますが、Spring JDBCが特定のクエリのアイテムのコレクションを((?)のような)自動的に処理する同様のケースを見ましたが、このケースを保証することはできません。
(この投稿への2番目のリンクを追加することはできません)で、いくつかの助けになるかもしれない有用な情報を見つけました。
2番目の要件(任意の数の引数で機能)が最も厳密な意味で満たされることはおそらく不可能であることを私は言うことができます:私が使用したすべてのデータベースは、実行されるクエリの長さの制限を課します。
以下のように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();
}
});
}
この場合、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();
}
});
}