在項目中,如果需要一次性插入或更新多條記錄,當然可以簡單地通過多次調用update()方法完成任務,但這不是最好的實現方案。更好的選擇是使用JDBCTemplate批量數據更改的方法。一般情況下,后者擁有更好的性能,因為更新的數據將被批量發送到數據庫中,它減少了對數據庫訪問的次數。JDBC有2個批量數據操作的方法:
- public int[] batchUpdate(String[] sql)
多條SQL語句組成一個數組,注意此處的sql語句不能帶參數,該方法以批量方式執行這些SQL語句。Spring在內部使用JDBC提供的批量更新API完成操作,如果底層的JDBC Driver不支持批量更新操作,Spring將采用逐條更新的方式模擬批量更新。
- int[] batchUpdate(String sql,BatchPreparedStatementSetter pss)
使用本方法對於同一結構的帶參SQL語句多次進行數據更新操作。通過BatchPreparedStatementSetter回調接口進行批量參數的綁定工作。BatchPreparedStatementSetter定義了兩個方法:
int getBatchSize():指定本批次的大小
void setValues(PreparedStatement ps,int i):為給定的PreparedStatement設置參數
示例如下:
private void addUsers(final List<User> userList) { final String sql = "insert into user(username,age) values(?,?)"; jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int index) throws SQLException { User user = userList.get(index); ps.setString(1, user.getUsername()); ps.setInt(2, user.getAge()); } public int getBatchSize() { return userList.size(); } }); }
需要注意的是BatchPreparedStatementSetter是一次性地批量提交數據,而不會分批提交,getBatchSize()是整批的大小。所以,如果希望將一個List中的數據通過BatchPreparedStatementSetter批量更新到數據庫中,getBatchSize()就應該設置為List的大小。如果List非常大,希望分多次批量提交,則可分段讀取這個大List並暫存到一個小的List中,再將這個小的List通過BatchPreparedStatemetSetter批量保存到數據庫中。