No MyBatis, a operação de inserção é geranciada pelo elemento <insert>. Os atributos principais incluem:
parameterType: classe ou apelido do parâmetro de entrada.keyColumn: especifica a coluna de chave primária auto-gerada, necessário para bancos de dados como PostgreSQL onde a chave não é o primeiro campo.keyProperty: define a propriedade do modelo de domínio onde o valor da chave gerada será atribuído.useGeneratedKeys: habilita o uso do método JDBCgetGeneratedKeyspara obter chaves auto-geradas (suportado por MySQL, SQL Server).statementType: tipo de instrução SQL (STATEMENT, PREPARED ou CALLABLE).flushCache: controla se o cache secundário e local deve ser limpo após a operação.timeout: tempo limite para a execução da operação.databaseId: identifica o fabricante do banco de dados para instruções SQL específicas.
Para uma inserção básica que retorna o número de registros afetados, a interface do mapper pode ser definida como:
int inserirAluno(Aluno aluno);
No arquivo XML correspondente:
<insert id="inserirAluno" parameterType="Aluno">
INSERT INTO alunos(nome, idade) VALUES(#{nome}, #{idade})
</insert>
Para obter a chave primária após a inserção, existem diferentes abordagens dependendo do banco de dados.
Para bancos de dados que spuortam chaves auto-geradas (ex.: MySQL):
<insert id="inserirAluno" parameterType="Aluno" useGeneratedKeys="true" keyProperty="id">
INSERT INTO alunos(nome, idade) VALUES(#{nome}, #{idade})
</insert>
Alternativamente, usando <selectKey>:
<insert id="inserirAluno" parameterType="Aluno">
<selectKey resultType="long" keyProperty="id" order="AFTER">
SELECT @@IDENTITY AS id
</selectKey>
INSERT INTO alunos(nome, idade) VALUES(#{nome}, #{idade})
</insert>
Para bancos de dados que não suportam chaves auto-geradas (ex.: Oracle):
<insert id="inserirAluno" parameterType="Aluno">
<selectKey keyProperty="id" resultType="long" order="BEFORE">
SELECT CAST(RANDOM() * 100000 AS INTEGER) FROM DUAL
</selectKey>
INSERT INTO alunos(id, nome, idade) VALUES(#{id}, #{nome}, #{idade})
</insert>
Nestes casos, o retorno da interface do mapper ainda é o número de registros inseridos, mas a chave primária é atribuída à propriedade id do objeto.
O sub-elemento <selectKey> permite executar uma consulta para obter valores de chave antes ou depois da inserção. Seus atributos incluem:
keyProperty: propriedade do modelo onde o resultado será atribuído.resultType: tipo do resultado da consulta.order: determina se a consulta é executada BEFORE ou AFTER a instrução INSERT.statementType: tipo da instrução SQL.
Para inserção em lote, várias técnicas podem ser usadas.
Usando <foreach> para múltiplas inserções individuais:
<insert id="inserirAlunos" parameterType="list">
<foreach collection="lista" item="aluno" separator=";">
INSERT INTO alunos(nome, idade) VALUES(#{aluno.nome}, #{aluno.idade})
</foreach>
</insert>
Este método executa inserções separadas, o que pode não garantir atomicidade e o retorno é apenas o resultado da última inserção.
Abordagem otimizada para SQL Server:
<insert id="inserirAlunos" parameterType="list">
WITH temporario AS
<foreach collection="lista" item="aluno" open="(" close=")" separator="UNION ALL">
SELECT #{aluno.nome} AS nome, #{aluno.idade} AS idade
</foreach>
INSERT INTO alunos(nome, idade) SELECT nome, idade FROM temporario
</insert>
Método genérico para inserção em lote:
INSERT INTO alunos(nome, idade)
<foreach collection="lista" item="aluno" open="(" close=")" separator="UNION ALL">
SELECT #{aluno.nome}, #{aluno.idade} FROM DUAL
</foreach>
Este código funciona em bencos como Oracle, ajustando a cláusula FROM conforme necessário para outros sistemas.