Spring中JDBC的批量操作

Spring框架也对JDBC进行了封装,它简化了JDBC操作,它是通过JdbcTemplate这个类来完成的。例如这个类的对象有一个batchUpdate()方法,可接收一个BatchPreparedStatementSetter的一个实现类实例。
1、JdbcTemplate的基本的批量操作
来看下面的代码:

public class JdbcActorDao implements ActorDao {
    private JdbcTemplate jdbcTemplate;
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    public int[] batchUpdate(final List<Actor> actors) {
        return this.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, actors.get(i).getFirstName());
            ps.setString(2, actors.get(i).getLastName());
            ps.setLong(3, actors.get(i).getId().longValue());
        }
        public int getBatchSize() {
            return actors.size();
        }
        });
    }
}

这个DAO的实现类中有一个,batchUpdate方法,用于批量更新一个演员信息的数据库表,方法执行了this.jdbcTemplate.batchUpdate()方法,而批量更新的关键是通过实现BatchPreparedStatementSetter这个接口来完成的。被实现的setValues()方法用于完成每次更新的操作,可多次被调用,getBatchSize()方法某次批量更新的数目,即setValues()方法调用的数次就是根据这个方法的返回值来决定的。
当然,JdbcTemplateNamedParameterJdbcTemplate这两个类,都提供了另外一个执行批量操作的方法,这个方法它不用实现某个接口,而是直接把要批量更新的数据集合放到batchUpdate()方法中就可以了,
A、含“?”占位符的语句

public class JdbcActorDao implements ActorDao {
    private JdbcTemplate jdbcTemplate;
    public void setDataSource(DataSource dataSource) {
    this.jdbcTemplate = new JdbcTemplate(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);
        }
        return this.jdbcTemplate.batchUpdate(
        "update t_actor set first_name = ?, last_name = ? where id = ?",
        batch);
    }

}

这种方式的批量更新在生成相关的参数时,要我们把各个参数的与SQL语句的参数对应顺序处理好,其中batch就是一个数组的数组,也就是说里面的每个子数组元素都存有相关的更新记录,子数组元素的顺序必须与SQL语句中参数的顺序一致。
B、含“锚点占位符”的语句
例如:

public class JdbcActorDao implements ActorDao {
private NamedParameterTemplate namedParameterJdbcTemplate;
public void setDataSource(DataSource dataSource) {
    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public int[] batchUpdate(List<Actor> actors) {
    return this.namedParameterJdbcTemplate.batchUpdate(
    "update t_actor set first_name = :firstName, last_name = :lastName where id = :id",
    SqlParameterSourceUtils.createBatch(actors.toArray()));
}

}

在这个方法中,它的第二个参数接收了一个SqlParameterSource类型的数组,这种形式的数组是通过SqlParameterSourceUtils.createBatch()方法来生成的,个人觉得这种方法的优点是,只要我们把相关对象数组传进去就行,相关的参数对应顺序及设置不用我们处理。
2、处理大数目的批量操作
有一种情况是,当执行批量更新的执行数量比较大时,我们想把这个数目拆分成更小的数目来批量执行。当然我们可以重复执行上述提到的方法,这个也是可以的。但batchUpdate()方法还有一个更简单的执行操作。来看下面的例子:

public class JdbcActorDao implements ActorDao {
    private JdbcTemplate jdbcTemplate;
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    public int[][] batchUpdate(final Collection<Actor> actors) {
        int[][] updateCounts = jdbcTemplate.batchUpdate(
        "update t_actor set first_name = ?, last_name = ? where id = ?",
        actors,
        100,
        new ParameterizedPreparedStatementSetter<Actor>() {
        public void setValues(PreparedStatement ps, Actor argument) throws SQLException {
        ps.setString(1, argument.getFirstName());
        ps.setString(2, argument.getLastName());
        ps.setLong(3, argument.getId().longValue());
        }
        });
        return updateCounts;
    }
}

这个例子中,要求批量操作的总次数是100,但这里的batchUpdate()方法自动帮我们把这个数目细化了,这个方法返回一个二维数组,其中这个数组中外层数组的长度就是代表本次细化的数目,里面的子数组的长度代表细化后每次要执行批量操作的次数,里面的数值代表每次操作中受影响的行数。

猜你喜欢

转载自blog.csdn.net/yangkaige111/article/details/80460445
今日推荐