?
このドキュメントでは、 php中國語ネットマニュアル リリース
絕大多數JDBC驅動針對批量調用相同的prepared statement對象提供了性能提升。通過將這些更新操作封裝到一個批量操作中,可以大量減少與數據庫的操作頻繁度。 本章節(jié)將詳細描述使用JdbcTemplate或者SimpleJdbcTemplate進行批量操作的流程。
JdbcTemplate的批量操作特性需要實現特定的接口BatchPreparedStatementSetter
來進行的, 通過實現這個接口,并將其傳入batchUpdate
方法進行調用。
這個接口有兩個方法需要實現。一個叫做getBatchSize
來提供當前需要批量操作的數量。另外一個方法是setValues
允許你為prepared statement設置參數。這個方法將在整個過程中被調用的次數,則取決于你在getBatchSize
中所指定的大小。
下面的示例展示了根據傳入的list參數更新actor表,而傳入的list同時作為批量操作的參數。
public class JdbcActorDao implements ActorDao { private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } public int[] batchUpdate(final List actors) { int[] updateCounts = jdbcTemplate.batchUpdate( "update t_actor set first_name = ?, last_name = ? where id = ?", new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { ps.setString(1, ((Actor)actors.get(i)).getFirstName()); ps.setString(2, ((Actor)actors.get(i)).getLastName()); ps.setLong(3, ((Actor)actors.get(i)).getId().longValue()); } public int getBatchSize() { return actors.size(); } } ); return updateCounts; } // ... additional methods }
如果你是通過讀取文件進行批量操作,那么你可能需要一個特定的批量操作的數量,不過最后一次的批量操作,你可能沒有那么多數量的記錄。
在這種情況下,你可以實現InterruptibleBatchPreparedStatementSetter
接口,從而允許你在某些情況中斷批量操作,isBatchExhausted
方法允許你指定一個終止批量操作的信號量。
SimpleJdbcTemplate
類提供了另外一種批量操作的方式。無需實現一個特定的接口,你只需要提供所有在調用過程中要用到的參數,框架會遍歷這些參數值,并使用內置的prepared statement類進行批量操作。API將根據你是否使用命名參數而有所不同。對于使用命名參數的情況,你需要提供一個SqlParameterSource
的數組, 其中的每個元素將將作為批量操作的參數。
你可以使用SqlParameterSource.createBatch
方法,通過傳入一個JavaBean的數組或者一個包含了參數鍵值對的Map數組來創(chuàng)建這個數組。
下面的示例展示了使用命名參數進行批量更新的方法:
public class JdbcActorDao implements ActorDao { private SimpleJdbcTemplate simpleJdbcTemplate; public void setDataSource(DataSource dataSource) { this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource); } public int[] batchUpdate(final List<Actor> actors) { SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(actors.toArray()); int[] updateCounts = simpleJdbcTemplate.batchUpdate( "update t_actor set first_name = :firstName, last_name = :lastName where id = :id", batch); return updateCounts; } // ... additional methods }
對于使用傳統(tǒng)的“?”作為參數占位符的情況,你可以傳入一個List,包含了所有需要進行批量更新的對象。這樣的對象數組必須與每個SQL Statement的占位符以及他們在SQL Statement中出現的位置一一對應。
下面是同樣的例子,使用的傳統(tǒng)的“?”作為參數占位符:
public class JdbcActorDao implements ActorDao { private SimpleJdbcTemplate simpleJdbcTemplate; public void setDataSource(DataSource dataSource) { this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource); } public int[] batchUpdate(final List<Actor> actors) { List<Object[]> batch = new ArrayList<Object[]>(); for (Actor actor : actors) { Object[] values = new Object[] { actor.getFirstName(), actor.getLastName(), actor.getId()}; batch.add(values); } int[] updateCounts = simpleJdbcTemplate.batchUpdate( "update t_actor set first_name = ?, last_name = ? where id = ?", batch); return updateCounts; } // ... additional methods }
所有的批量更新的方法都會返回一組int的數組,表示在整個操作過程中有多少記錄被批量更新。 這個數量是由JDBC驅動所返回的,有時這個返回并不可靠,尤其對于某些JDBC驅動只是簡單的返回-2作為返回值。