Howto возвращает идентификаторы на вставках с Ibatis (с ключевым словом RETURNING)
Я использую iBatis/Java и Postgres 8.3.
Когда я делаю вставку в ibatis, мне нужно вернуть id.
Я использую следующую таблицу для описания моего вопроса:
CREATE TABLE sometable ( id serial NOT NULL, somefield VARCHAR(10) );
Последовательность sometable_id_seq
получает автогенерирование, запустив инструкцию create.
В настоящее время я использую следующую карту sql:
<insert id="insertValue" parameterClass="string" >
INSERT INTO sometable ( somefield ) VALUES ( #value# );
<selectKey keyProperty="id" resultClass="int">
SELECT last_value AS id FROM sometable_id_seq
</selectKey>
</insert>
Кажется, это способ ibatis восстановить вновь вставленный идентификатор. Ibatis сначала запускает оператор INSERT, а затем запрашивает последовательность для последнего id.
У меня есть сомнения, что это будет работать со многими параллельными вставками. (обсуждался в этом вопросе)
Я хотел бы использовать следующую инструкцию с помощью ibatis:
INSERT INTO sometable ( somefield ) VALUES ( #value# ) RETURNING id;
Но когда я пытаюсь использовать его в <insert>
sqlMap, ibatis не возвращает идентификатор. Кажется, что требуется тег <selectKey>
.
Итак, возникает вопрос:
Как я могу использовать вышеуказанное утверждение с помощью ibatis?
Ответы
Ответ 1
Элемент <selectKey>
является дочерним элементом элемента <insert>
, а его содержимое выполняется перед основным оператором INSERT
. Вы можете использовать два подхода.
Получить ключ после того, как вы вставили запись
Этот подход работает в зависимости от вашего драйвера. Threading может быть проблемой с этим.
Извлечение ключа перед вставкой записи
Этот подход позволяет избежать проблем с потоками, но это большая работа. Пример:
<insert id="insert">
<selectKey keyProperty="myId"
resultClass="int">
SELECT nextVal('my_id_seq')
</selectKey>
INSERT INTO my
(myId, foo, bar)
VALUES
(#myId#, #foo#, #bar#)
</insert>
На стороне Java вы можете сделать
Integer insertedId = (Integer) sqlMap.insert("insert", params)
Это даст вам ключ, выбранный из последовательности my_id_seq
.
Ответ 2
Вот простой пример:
<statement id="addObject"
parameterClass="test.Object"
resultClass="int">
INSERT INTO objects(expression, meta, title,
usersid)
VALUES (#expression#, #meta#, #title#, #usersId#)
RETURNING id
</statement>
И в коде Java:
Integer id = (Integer) executor.queryForObject("addObject", object);
object.setId(id);
Этот способ лучше, чем использование:
- Это проще,
- Он не просил узнать имя последовательности (что обычно скрыто от разработчиков postgresql).