Java で JDBC を使用して MySQL への batchInsert (バルクインサート) で
嵌った・・・
JDBC で batchInsert をやるには、
- rewriteBatchedStatements = true
- useServerPrepStmts = false
のオプションが必要になるが、指定しても特定のテーブルだけ効かない・・・
テーブル
CREATE TABLE testtbl(selector_type INT);
Java
Class.forName("com.mysql.jdbc.Driver").newInstance();
Properties prop = new Properties();
prop.setProperty("user", "testuser");
prop.setProperty("password", "password");
prop.setProperty("characterEncoding", "utf8");
prop.setProperty("rewriteBatchedStatements", "true");
prop.setProperty("useServerPrepStmts", "false");
try (Connection con= DriverManager.getConnection("jdbc:mysql://localhost/testdb", prop)) {
PreparedStatement stmt = con.prepareStatement("INSERT INTO testtbl (selector_type) VALUES (?)");
for (int i = 0; i < 10; ++i) {
stmt.setInt(1, i);
stmt.addBatch();
}
stmt.executeBatch();
}
結果
2019-02-27T02:28:18.112397Z 19 Query INSERT INTO testtbl (selector_type) VALUES (0);
2019-02-27T02:28:18.112734Z 19 Query INSERT INTO testtbl (selector_type) VALUES (1);
2019-02-27T02:28:18.112853Z 19 Query INSERT INTO testtbl (selector_type) VALUES (2);
2019-02-27T02:28:18.113839Z 19 Query INSERT INTO testtbl (selector_type) VALUES (3);
2019-02-27T02:28:18.113953Z 19 Query INSERT INTO testtbl (selector_type) VALUES (4);
2019-02-27T02:28:18.114038Z 19 Query INSERT INTO testtbl (selector_type) VALUES (5);
2019-02-27T02:28:18.114121Z 19 Query INSERT INTO testtbl (selector_type) VALUES (6);
2019-02-27T02:28:18.114202Z 19 Query INSERT INTO testtbl (selector_type) VALUES (7);
2019-02-27T02:28:18.114291Z 19 Query INSERT INTO testtbl (selector_type) VALUES (8);
2019-02-27T02:28:18.114370Z 19 Query INSERT INTO testtbl (selector_type) VALUES (9)
VALUES のあとにスペースが必要との情報もあったが、
既についてる・・・
JDBC ドライバーのソースを追ってみたところ、PreparedStatement クラスに
if (StringUtils.indexOfIgnoreCase(statementStartPos, sql, "SELECT", "\"'`", "\"'`", StringUtils.SEARCH_MODE__MRK_COM_WS) != -1) {
return false;
}
的なコードが・・・
SELECT INSERT を除外しているようだが、もしやということで、カラム名をバッククウォートで囲ったところ
Java
snip ...
PreparedStatement stmt = con.prepareStatement("INSERT INTO testtbl (`selector_type`) VALUES (?)");
snip ...
結果
2019-02-27T02:28:39.536756Z 20 Query INSERT INTO testtbl (`selector_type`) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)
連結されて、
1 文で実行されることに!
SQL 文の中に SELECT という文字があるとダメな模様。
さらに調べてみると
、既に報告が上がっていた。
https://bugs.mysql.com/bug.php?id=81468
2016 年 5 月・・・