web-dev-qa-db-fra.com

JDBC insère plusieurs lignes

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();
34
DrXCheng

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.

25
Filipe Fedalto

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(); 
37
Reimeus

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();
        }
    }
} 
1
Memin
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();
        }
    });
}
0
sanjaykumar