spring批量插入使用hibernateTemplate,JdbcTemplate

时间:2010-02-27 14:12:17

标签: sql hibernate spring batch-processing

我在Spring中有一些与批量插入相关的问题。

当我做那样的事情时:

public void save(Car car) {
  String sql1 = "insert into Car values (1, 'toyota')";
  String sql2 = "insert into Car values (2, 'chrysler')";
  String sql3 = "insert into Car values (3, 'infinity')";

  String[] tab = new String[2];
  tab[0] = sql1;
  tab[1] = sql2;
  tab[2] = sql3;

  getJdbcTemplate().update(sql1);
  getJdbcTemplate().update(sql2);
  getJdbcTemplate().update(sql3);

  // getJdbcTemplate().batchUpdate(tab);
}

在mysql日志文件中我看到:

1  Query       insert into Car values (1, 'toyota')
2  Query       insert into Car values (2, 'chrysler')
3  Query       insert into Car values (3, 'infinity')

所以我们有3个插入语句(和3个网络调用)。

当我在日志文件中使用getJdbcTemplate().batchUpdate(tab)时,我可以看到:

1094 [main] DEBUG org.springframework.jdbc.core.JdbcTemplate - 执行3个语句的SQL批量更新 1110 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - 从DataSource获取JDBC连接 1110 [main] DEBUG org.springframework.jdbc.datasource.DriverManagerDataSource - 创建新的JDBC DriverManager连接到[jdbc:mysql:// localhost:3306 / test?useServerPrepStmts = true] 1610 [main] DEBUG org.springframework.jdbc.support.JdbcUtils - JDBC驱动程序支持批量更新

并在mysql日志中:

1  Query       insert into Car values (1, 'toyota')
1  Query       insert into Car values (2, 'chrysler')
1  Query       insert into Car values (3, 'infinity')

据我所知,在后台,在语句对象上调用addBatch方法,所有这些操作都是同时执行的。额外的好处是减少网络呼叫。我的推理是否正确?

我在HibernateTemplate中寻找类似的东西。我可以这样做:

  getHibernateTemplate().saveOrUpdateAll(Arrays.asList(new Car(4, "infinity"), new Car(5, "ford")));

在这种情况下,我可以在日志文件中看到:

3  Prepare     select car_.id, car_.name as name0_ from Car car_ where car_.id=?
3  Prepare     select car_.id, car_.name as name0_ from Car car_ where car_.id=?
3  Prepare     insert into Car (name, id) values (?, ?)

所以似乎所有事情都是一次性完成的,就像为getJdbcTemplate()所做的那样.updateBatch(...)

如果我错了,请纠正我。

1 个答案:

答案 0 :(得分:3)

要生成类似于Hibernate的结果(使用预准备语句),您应该使用JdbcTemplate.batchUpdate(String, BatchPreparedStatementSetter)。像这样:

final List<Car> cars = Arrays.asList(...);

getJdbcTemplate().batchUpdate("insert into Car (name, id) values (?, ?);",
    new BatchPreparedStatementSetter() {
        private int i = 0;
        public int getBatchSize() { return cars.size(); }
        public void setValues(PreparedStatement ps) {
            ps.setString(1, cars.get(i).getName());
            ps.setInt(2, cars.get(i).getId());
            i++;
        }
    });