Возвращаемые значения из методов MyBatis <insert>

У меня есть проект Java, который использует MyBatis для доступа к базе данных PostgreSQL. PostgreSQL позволяет возвращать поля только что созданной строки после инструкции INSERT, и я хочу использовать ее для возврата автоматически сгенерированных BIGSERIAL id вновь созданных записей. Итак, я изменяю команду INSERT в XML для использования функции PostgreSQL, добавляю атрибут resultType="long" к тегу <insert>, а в интерфейсе Java для mapper я установил метод вставки для возврата long вместо void.

Когда я пытаюсь запустить это, я получаю org.xml.sax.SAXParseException, говорящий, что Attribute "resultType" must be declared for element type "insert".

Теперь, когда я изменяю тег <insert> на <select>, все работает нормально, но мне мешает, что я использую тег <select> для выполнения инструкции INSERT.

Есть ли способ сделать методы, сопоставленные с тегами <insert>, возвращать результаты или MyBatis не предназначен для этого, и я должен просто хранить их как теги <select>?

Ответ 1

Возвращаемый тип метода сопоставленной вставки может быть void или int (в этом случае он вернет число вставленной строки). Вы можете сделать следующий механизм для возврата сгенерированного идентификатора:

<insert id="insert" parameterClass="MyParameter">
  <selectKey order="AFTER" keyProperty="id" resultType="long">
    SELECT currval('my_seq')
  </selectKey>
  INSERT INTO mytable(col1, col2) VALUES (#{val1}, #{val2})
</isnert>

Это установит сгенерированный столбец id в свойство id вашего класса параметров. После этого объект, который вы передали как параметр, сгенерировал id в свойстве.

Ответ 2

Вы можете использовать следующее. В xml

 <insert id="insertNewUser" parameterType="User">
            <selectKey keyProperty="userId" resultType="Integer" order="BEFORE">
                select NEXTVAL('base.user_id_seq')
            </selectKey>
            INSERT INTO base.user(
                user_id, user_name)
            VALUES (#{userId}, #{userName});
    </insert>

В Java-классе, откуда вы вызвали метод для вставки, вы можете получить значение, вызвав user.getUserId().

В основном следующий val хранится внутри переменной объекта. Here userId inside User.

Ответ 3

Вы также можете использовать сгенерированные ключи:

  <insert id="create" parameterType="Skupina" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        INSERT INTO ODBOR 
            (NAZEV, POPIS, ZKRATKA, WEBROLE, JEODBOR, AKTIVNI)
        VALUES 
            (#{nazev}, #{popis}, #{webrole}, #{webrole}, false, #{aktivni})
  </insert>

После вставки параметр имеет свойство id для значения из столбца id.

Ответ 4

Есть два способа (по крайней мере, я знаю), чтобы получить идентификатор одной вставленной записи:

Например, у нас есть класс EntityDao:

public class EntityDao {
     private Long id;
     private String name;
     // other fields, getters and setters
}

1. Использование тега insert и возврат экземпляра объекта

Интерфейс MyBatis

public interface EntityDaoMapper {
    EntityDao insert(EntityDao entity);
}

MyBatis XML mapper:

<insert id="insert" parameterType="com.package.EntityDao" useGeneratedKeys="true" keyColumn="entity_id" keyProperty="id">
    INSERT INTO some_table (name, type, other_fields, etc)
    VALUES (#{name}, #{type}, #{other_fields}, #{etc}) 
</insert>

Пример кода:

    EntityDao saved = entityDaoMapper.insert(entityToSave);
    System.out.println(saved.getId());

2. Использование тегов select и resultType для возврата только идентификатора записи

Интерфейс MyBatis

public interface EntityDaoMapper {
    Long insert(EntityDao entity);
}

MyBatis XML mapper:

<select id="insert" parameterType="com.package.EntityDao" resultType="long">
    INSERT INTO some_table (name, type, other_fields, etc)
    VALUES (#{name}, #{type}, #{other_fields}, #{etc}) 
    RETURNING entity_id       <-- id only or many fields
</select>

Пример кода:

Long id = entityDaoMapper.insert(entityToSave);
System.out.println(id);