J'utilise maintenant le batch:
String query = "INSERT INTO table (id, name, value) VALUES (?, ?, ?)";
PreparedStatement ps = connection.prepareStatement(query);
for (Record record : records) {
ps.setInt(1, record.id);
ps.setString(2, record.name);
ps.setInt(3, record.value);
ps.addBatch();
}
ps.executeBatch();
Je me demande simplement si le code ci-dessus est équivalent au code suivant. Sinon, lequel est le plus rapide?
String query = "INSERT INTO table (id, name, value) VALUES ";
for (Record record : records) {
query += "(" + record.id + ",'" + record.name + "'," + record.value + "),";
}
query = query.substring(1, query.length() - 1);
PreparedStatement ps = connection.prepareStatement(query);
ps.executeUpdate();
Tout d'abord, avec la concaténation de chaînes de requête, vous perdez non seulement la conversion de type native aux méthodes PreparedStatement, mais vous êtes également vulnérable à l'exécution de code malveillant dans la base de données.
Deuxièmement, les PreparedStatements sont précédemment mis en cache dans la base de données même, et cela donne déjà une très bonne amélioration des performances par rapport aux instructions simples.
executeBatch
aura des performances améliorées par rapport à executeUpdate
tant que la validation automatique est définie sur false:
connection.setAutoCommit(false);
PreparedStatement ps = connection.prepareStatement(query);
for (Record record : records) {
// etc.
ps.addBatch();
}
ps.executeBatch();
connection.commit();
Vous pouvez rencontrer de sérieux problèmes de performances si le nombre d'éléments que vous souhaitez insérer est important. Par conséquent, il est plus sûr de définir une taille de lot et d'exécuter constamment la requête lorsque la taille de lot est atteinte.
Quelque chose comme l'exemple de code suivant devrait fonctionner. Pour l'histoire complète de l'utilisation efficace de ce code, veuillez consulter ceci lien .
private static void insertList2DB(List<String> list) {
final int batchSize = 1000; //Batch size is important.
Connection conn = getConnection();
PreparedStatement ps = null;
try {
String sql = "INSERT INTO theTable (aColumn) VALUES (?)";
ps = conn.prepareStatement(sql);
int insertCount=0;
for (String item : list) {
ps.setString(1, item);
ps.addBatch();
if (++insertCount % batchSize == 0) {
ps.executeBatch();
}
}
ps.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
System.exit(1);
}
finally {
try {
ps.close();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void insertBatch(final List<Record > records ) {
String query = "INSERT INTO table (id, name, value) VALUES (?, ?, ?)";
GenericDAO.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Record record = records .get(i);
ps.setInt(1, record.id);
ps.setString(2, record.name);
ps.setInt(3, record.value);
}
@Override
public int getBatchSize() {
return records.size();
}
});
}