JdbcTemplate 执行与更新
您可以使用 JdbcTemplate 的 execute()方法执行 SQL 陈述,例如:
jdbcTemplate.execute("CREATE TABLE USER (user_id integer, name varchar(100))");
如果是 UPDATE 或 INSERT,您可以使用 update()方法,update()方法有数个重载(Overload)版本, 例如 接受实作 org.springframework.jdbc.core.PreparedStatementCreator 介面的 物件, PreparedStatementCreator 介面的定义如下:
package org.springframework.jdbc.core; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public interface PreparedStatementCreator { PreparedStatement createPreparedStatement(Connection con) throws SQLException; }
例如您可以将 使用 JdbcTemplate 中UserDAO的insert()方法改写如下:
... public void insert(User user) { final String name = user.getName(); final int age = user.getAge().intValue(); jdbcTemplate.update( new PreparedStatementCreator() { public PreparedStatement createPreparedStatement( Connection con) throws SQLException { String sql ="INSERT INTO user (name,age) VALUES(?,?)"; PreparedStatement ps =con.prepareStatement(sql); ps.setString(1, name); ps.setInt(2, age); return ps; } ... } });
在这个例子 中,可以使 用 PreparedStatement 预先编译 SQL , JdbcTemplate 上实现了 Template‐callback 机制,在执行 JDBC 的流程中,必要时会呼叫 callback 方法。 与 PreparedStatementCreator 互补的介面是 org.springframework.jdbc.core.PreparedStatementSetter 介面:
package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; public interface PreparedStatementSetter { void setValues(PreparedStatement ps) throws SQLException; }
例如您可以将 使用 JdbcTemplate 中UserDAO的insert()方法改写如下:
... public void insert(User user) { final String name = user.getName(); final int age = user.getAge().intValue(); jdbcTemplate.update("INSERT INTO user (name,age) VALUES(?,?)", new PreparedStatementSetter() { public void setValues(PreparedStatement ps) throws SQLException { ps.setString(1, name); ps.setInt(2, age); } ... } });
JdbcTemplate 会自动建立 PreparedStatementCreator 的实例,以提供传递给 setValues() 方法 的 PreparedStatement物件。 您也可以直接提供SQL,就如 使用 JdbcTemplate 中所示范的UserDAO中的insert()方法:
... public void insert(User user) { String name = user.getName(); int age = user.getAge().intValue(); jdbcTemplate.update( "INSERT INTO user (name,age) " + "VALUES('" + name + "'," + age + ")"); } ...
在直接下SQL语句时,也可以使用"?"作为占位字元,并使用物件阵列作为引数传递给JdbcTemplate 的update()方法,例如改写 使用 JdbcTemplate 中所示范的UserDAO中的insert()方法:
... public void insert(User user) { jdbcTemplate.update( "INSERT INTO user (name, age) VALUES(?,?)", new Object[] {user.getName(), user.getAge()}); } ...
JdbcTemplate 会自动建立 PreparedStatementCreator 与 PreparedStatementSetter 的实例,然而这 些细节您不用理会,您只要提供 SQL 与引数就好了。 如果需要批次处理时,可以实作 org.springframework.jdbc.core.BatchPreparedStatementSetter 介面:
package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; public interface BatchPreparedStatementSetter { void setValues(PreparedStatement ps,int i) throws SQLException; int getBatchSize(); }
例如您可以在 使用 JdbcTemplate 中的IUserDAO介面及UserDAO类别上增加一个insertUsers()方 法的定义与实作,像是以下的内容:
... public int[] insertUsers(final List users) { String sql = "INSERT INTO user (name,age) VALUES(?,?)"; BatchPreparedStatementSetter setter = new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { User user = (User) users.get(i); ps.setString(1, user.getName()); ps.setInt(2, user.getAge().intValue()); } public int getBatchSize() { return users.size(); } }; return jdbcTemplate.batchUpdate(sql, setter); } ...
如果您的 JDBC 驱动程式支援批次处理的话,则直接使用它的功能,如果不支援,则 Spring 会自 动一个一个处理更新以模拟批次处理。