JDBC insert multiple rows

Viewed 66749

I am now using 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();

I am just wondering if the above code is equivalent to the following code. If not, which is faster?

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();
6 Answers

You can face a serious performance issue if the number of items that you want to insert is large. Therefore, it is safer to define a batch size, and constantly execute the query when the batch size is reached.

Something like the following example code should work. For the full story of how using this code efficiently, please see this link.

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();
        }
    }
} 

In case that your records size is less than or equal to 1000 the following code is better than both of your codes:

StringBuilder query = new StringBuilder("INSERT INTO table (id, name, value) VALUES ");

if (records.size() <= 1000) {
    
    for (int i = 0; i < records.size(); i++)
        query.append("(?, ?, ?), ");

    query = new StringBuilder(query.substring(1, query.length() - 1));

    PreparedStatement ps = connection.prepareStatement(query.toString());

    for (int i = 0; i < records.size(); i++) {
        ps.setInt((i * 3) + 1, record.id);
        ps.setString((i * 3) + 2, record.name);
        ps.setInt((i * 3) + 3, record.value);
    }
    
    ps.executeUpdate();
    
}

In this way you are using PreparedStatement and create it dynamically depending the size of your record list using multiple values clause in one insert query

Related