пружинная вставка с использованием hibernateTemplate, JdbcTemplate - PullRequest
2 голосов
/ 27 февраля 2010

У меня есть несколько вопросов, связанных с пакетной вставкой в ​​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 - выполнение пакетного обновления SQL для 3 операторов 1110 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - извлечение соединения 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 Ответ

3 голосов
/ 27 февраля 2010

Для получения результата, похожего на 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++;
        }
    });
...