Saya ingin memasukkan beberapa baris ke dalam tabel MySQL sekaligus menggunakan Java. Jumlah baris dinamis. Di masa lalu saya melakukan ...
for (String element : array) {
myStatement.setString(1, element[0]);
myStatement.setString(2, element[1]);
myStatement.executeUpdate();
}
Saya ingin mengoptimalkan ini untuk menggunakan sintaks yang didukung MySQL:
INSERT INTO table (col1, col2) VALUES ('val1', 'val2'), ('val1', 'val2')[, ...]
tetapi dengan PreparedStatement
saya tidak tahu cara untuk melakukan ini karena saya tidak tahu sebelumnya berapa banyak elemen yang array
akan mengandung. Jika tidak mungkin dengan a PreparedStatement
, bagaimana lagi saya bisa melakukannya (dan masih lolos dari nilai dalam larik)?
sumber
connection.setAutoCommit(false);
danconnection.commit();
unduh.oracle.com/javase/tutorial/jdbc/basics/…i == entities.size()
Ketika driver MySQL digunakan, Anda harus mengatur parameter koneksi
rewriteBatchedStatements
ke true( jdbc:mysql://localhost:3306/TestDB?**rewriteBatchedStatements=true**)
.Dengan parameter ini pernyataan ditulis ulang menjadi penyisipan massal ketika tabel dikunci hanya sekali dan indeks diperbarui hanya sekali. Jadi jauh lebih cepat.
Tanpa parameter ini, satu-satunya keuntungan adalah kode sumber yang lebih bersih.
sumber
5.1.45
versi konektor mysql.rewriteBatchedStatements=true
tidak ada perolehan kinerja.Jika Anda dapat membuat pernyataan sql Anda secara dinamis, Anda dapat melakukan solusi berikut:
String myArray[][] = { { "1-1", "1-2" }, { "2-1", "2-2" }, { "3-1", "3-2" } }; StringBuffer mySql = new StringBuffer("insert into MyTable (col1, col2) values (?, ?)"); for (int i = 0; i < myArray.length - 1; i++) { mySql.append(", (?, ?)"); } myStatement = myConnection.prepareStatement(mySql.toString()); for (int i = 0; i < myArray.length; i++) { myStatement.setString(i, myArray[i][1]); myStatement.setString(i, myArray[i][2]); } myStatement.executeUpdate();
sumber
Jika Anda memiliki penambahan otomatis dalam tabel dan perlu mengaksesnya .. Anda dapat menggunakan pendekatan berikut ... Lakukan pengujian sebelum menggunakan karena getGeneratedKeys () dalam Pernyataan karena bergantung pada driver yang digunakan. Kode di bawah ini diuji pada Maria DB 10.0.12 dan Maria JDBC driver 1.2
Ingatlah bahwa meningkatkan ukuran tumpukan meningkatkan kinerja hanya sampai batas tertentu ... karena penyiapan saya, meningkatkan ukuran tumpukan di atas 500 sebenarnya menurunkan kinerja.
public Connection getConnection(boolean autoCommit) throws SQLException { Connection conn = dataSource.getConnection(); conn.setAutoCommit(autoCommit); return conn; } private void testBatchInsert(int count, int maxBatchSize) { String querySql = "insert into batch_test(keyword) values(?)"; try { Connection connection = getConnection(false); PreparedStatement pstmt = null; ResultSet rs = null; boolean success = true; int[] executeResult = null; try { pstmt = connection.prepareStatement(querySql, Statement.RETURN_GENERATED_KEYS); for (int i = 0; i < count; i++) { pstmt.setString(1, UUID.randomUUID().toString()); pstmt.addBatch(); if ((i + 1) % maxBatchSize == 0 || (i + 1) == count) { executeResult = pstmt.executeBatch(); } } ResultSet ids = pstmt.getGeneratedKeys(); for (int i = 0; i < executeResult.length; i++) { ids.next(); if (executeResult[i] == 1) { System.out.println("Execute Result: " + i + ", Update Count: " + executeResult[i] + ", id: " + ids.getLong(1)); } } } catch (Exception e) { e.printStackTrace(); success = false; } finally { if (rs != null) { rs.close(); } if (pstmt != null) { pstmt.close(); } if (connection != null) { if (success) { connection.commit(); } else { connection.rollback(); } connection.close(); } } } catch (SQLException e) { e.printStackTrace(); } }
sumber
@Ali Shakiba kode Anda perlu beberapa modifikasi. Bagian kesalahan:
for (int i = 0; i < myArray.length; i++) { myStatement.setString(i, myArray[i][1]); myStatement.setString(i, myArray[i][2]); }
Kode yang diperbarui:
String myArray[][] = { {"1-1", "1-2"}, {"2-1", "2-2"}, {"3-1", "3-2"} }; StringBuffer mySql = new StringBuffer("insert into MyTable (col1, col2) values (?, ?)"); for (int i = 0; i < myArray.length - 1; i++) { mySql.append(", (?, ?)"); } mysql.append(";"); //also add the terminator at the end of sql statement myStatement = myConnection.prepareStatement(mySql.toString()); for (int i = 0; i < myArray.length; i++) { myStatement.setString((2 * i) + 1, myArray[i][1]); myStatement.setString((2 * i) + 2, myArray[i][2]); } myStatement.executeUpdate();
sumber
myArray
memiliki panjang yang lebih besar dari batas tersebut, Anda akan mendapatkan pengecualian. Dalam kasus saya, saya memiliki batas 1.000 baris yang memunculkan kebutuhan untuk eksekusi batch, karena saya berpotensi memperbarui lebih dari 1.000 baris pada proses tertentu. Jenis pernyataan ini secara teoritis akan berfungsi dengan baik jika Anda tahu Anda memasukkan kurang dari jumlah maksimum yang diperbolehkan. Sesuatu yang perlu diingat.kami dapat mengirimkan beberapa pembaruan bersama-sama di JDBC untuk mengirimkan pembaruan batch.
kita dapat menggunakan objek Statement, PreparedStatement, dan CallableStatement untuk update bacth dengan menonaktifkan autocommit
Fungsi addBatch () dan executeBatch () tersedia dengan semua objek pernyataan untuk memiliki BatchUpdate
di sini metode addBatch () menambahkan satu set pernyataan atau parameter ke batch saat ini.
sumber