идентификация из sql вставки через jdbctemplate

Можно ли получить @@identity из вставки SQL при вызове шаблона Spring jdbc? Если да, то как?


person javamonkey79    schedule 03.11.2009    source источник


Ответы (4)


Метод JDBCTemplate.update перегружен для получения объекта с именем GeneratedKeyHolder, который можно использовать для получения автоматически сгенерированного ключа. Например (код взят из здесь ):

final String INSERT_SQL = "insert into my_test (name) values(?)";
final String name = "Rob";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(
    new PreparedStatementCreator() {
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
            PreparedStatement ps =
                connection.prepareStatement(INSERT_SQL, new String[] {"id"});
            ps.setString(1, name);
            return ps;
        }
    },
    keyHolder);
// keyHolder.getKey() now contains the generated key
person Jason Gritman    schedule 03.11.2009
comment
Это будет тот лайнер, который я ищу здесь. Хороший. Грустно то, что я видел ссылку, но пропустил ее из-за этого: часть стандарта JDBC 3.0. (Я не думаю, что мы используем JDBC 3.0, но я также не думаю, что это актуально). - person javamonkey79; 03.11.2009
comment
Он получает настоящий лайнер в Java 8 с лямбда-выражениями \m/ - person fabwu; 17.12.2015
comment
Что, если сгенерированный ключ — не число, а строка? - person DCameronMauch; 10.01.2019
comment
в случае использования NEWID, который представляет собой хэш (строку), как бы вы его вернули? - person Tiago Medici; 21.02.2020
comment
KeyHolder имеет не только методы getKey(), но также методы getKeys() и getKeyList(), возвращающие значения ключей в виде объектов. - person yuriy.weiss; 04.03.2020
comment
Должна ли таблица (my_test) иметь свойство IDENTITY? без него я получаю нулевое исключение. - person Jonathan Hagen; 24.09.2020

Как насчет SimpleJdbcInsert.executeAndReturnKey? Он принимает две формы, в зависимости от ввода:

(1) Ввод Map

public java.lang.Number executeAndReturnKey(java.util.Map<java.lang.String,?> args)

Описание скопировано из интерфейса: SimpleJdbcInsertOperations

Выполните вставку, используя переданные значения, и верните сгенерированный ключ. Для этого необходимо, чтобы были указаны имена столбцов с автоматически сгенерированными ключами. Этот метод всегда будет возвращать KeyHolder, но вызывающая сторона должна убедиться, что он действительно содержит сгенерированные ключи.

Указано:

executeAndReturnKey в интерфейсе SimpleJdbcInsertOperations

Параметры:

args - Map containing column names and corresponding value

Возвраты:

the generated key value

(2) Ввод SqlParameterSource

public java.lang.Number executeAndReturnKey(SqlParameterSource< /а>parameterSource)

Описание скопировано из интерфейса: SimpleJdbcInsertOperations

Выполните вставку, используя переданные значения, и верните сгенерированный ключ. Для этого необходимо, чтобы были указаны имена столбцов с автоматически сгенерированными ключами. Этот метод всегда будет возвращать KeyHolder, но вызывающая сторона должна убедиться, что он действительно содержит сгенерированные ключи.

Указано:

executeAndReturnKey в интерфейсе SimpleJdbcInsertOperations

Параметры:

parameterSource - SqlParameterSource containing values to use for insert

Возвраты:

сгенерированное значение ключа.

person todd.pierzina    schedule 11.11.2009
comment
Вау, я действительно не знал об этом классе - вроде прикольно. Спасибо. +1 - person javamonkey79; 12.11.2009
comment
Эта версия мне нравится больше, чем версия с PreparedStatementCreator. - person ruslanys; 13.08.2015

Добавление подробных примечаний/образца кода в ответ todd.pierzina

jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
        jdbcInsert.withTableName("TABLE_NAME").usingGeneratedKeyColumns(
                "Primary_key");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("Column_NAME1", bean.getval1());
        parameters.put("Column_NAME2", bean.getval2());
        // execute insert
        Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(
                parameters));
           // convert Number to Int using ((Number) key).intValue()
            return ((Number) key).intValue();
person Sheetal Mohan Sharma    schedule 07.02.2014
comment
Я столкнулся с этим исключением: org.springframework.dao.InvalidDataAccessResourceUsageException: функция getGeneratedKeys не поддерживается этой базой данных - person Az.MaYo; 01.04.2016
comment
@ Az.MaYo - Ваша проблема может быть связана с версией драйвера JDBC. - person Sheetal Mohan Sharma; 18.04.2016

Я не знаю, есть ли "однострочник", но, похоже, это помогает (по крайней мере, для MSSQL):

// -- call this after the insert query...
this._jdbcTemplate.queryForInt( "select @@identity" );

Достойная статья здесь.

person javamonkey79    schedule 03.11.2009
comment
Страница не найдена по ссылке. - person Ruslan; 09.05.2017
comment
Для SQL Server @@identity возвращает последний идентификатор, сгенерированный для любой таблицы в базе данных в текущем сеансе. Так, например, если ваша вставка вызывает срабатывание триггера, который также создает новый идентификатор в какой-либо таблице, вы получите это значение. В большинстве случаев вы никогда не захотите использовать @@identity. - person Rick; 01.10.2018