O MyBatis é uma das soluções mais adotadas para persistência de dados em aplicações Spring Boot. Este artigo demonstra como estender suas interfaces Mappper com novas operações de banco de dados, utilizando tanto anotações quanto configuração XML.
Estrutura Inicial do Projeto
Considere uma aplicação de gestão de clientes. Primeiro, definimos a entidade:
public class Cliente {
private Long codigo;
private String nomeCompleto;
private String enderecoEletronico;
private LocalDateTime dataCadastro;
// métodos de acesso
}
Abordagem com Anotações
A forma mais direta é utilizar as anotações do MyBatis diretamente na interface:
@Mapper
public interface ClienteMapper {
@Select("SELECT * FROM clientes WHERE codigo = #{codigo}")
Cliente localizarPorCodigo(Long codigo);
@Insert("INSERT INTO clientes(nome_completo, endereco_eletronico) " +
"VALUES(#{nomeCompleto}, #{enderecoEletronico})")
@Options(useGeneratedKeys = true, keyProperty = "codigo")
void inserir(Cliente cliente);
}
Para adicionar uma busca por endereço eletrônico, simplesmente expandimos a interface:
@Select("SELECT * FROM clientes WHERE endereco_eletronico = #{email}")
Cliente localizarPorEmail(String email);
Abordagem com XML
Para consultas mais elaboradas, prefira arquivos XML. A estrutura do ClienteMapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="com.exemplo.persistencia.ClienteMapper">
<resultMap id="mapeamentoCliente" type="Cliente">
<id property="codigo" column="codigo"/>
<result property="nomeCompleto" column="nome_completo"/>
<result property="enderecoEletronico" column="endereco_eletronico"/>
<result property="dataCadastro" column="data_cadastro"/>
</resultMap>
<select id="localizarPorCodigo" resultMap="mapeamentoCliente">
SELECT * FROM clientes WHERE codigo = #{codigo}
</select>
<!-- Nova consulta adicionada -->
<select id="localizarPorEmail" resultMap="mapeamentoCliente">
SELECT * FROM clientes
WHERE endereco_eletronico = #{email}
AND ativo = true
</select>
<select id="listarRecentes" resultMap="mapeamentoCliente">
SELECT * FROM clientes
WHERE data_cadastro >= #{dataLimite}
ORDER BY data_cadastro DESC
</select>
</mapper>
Integração com a Camada de Serviço
A interface Mapper é injetada no serviço:
@Service
public class GestaoClientes {
private final ClienteMapper persistencia;
public GestaoClientes(ClienteMapper persistencia) {
this.persistencia = persistencia;
}
public Cliente buscarPorEmail(String email) {
return persistencia.localizarPorEmail(email);
}
public List<Cliente> obterCadastrosDaSemana() {
LocalDateTime seteDiasAtras = LocalDateTime.now().minusDays(7);
return persistencia.listarRecentes(seteDiasAtras);
}
}
Configuração do Spring Boot
No application.yml:
mybatis:
mapper-locations: classpath:/mapeadores/**/*.xml
type-aliases-package: com.exemplo.dominio
configuration:
map-underscore-to-camel-case: true
default-fetch-size: 100
Testando a Nova Funcionalidade
@SpringBootTest
class ClienteMapperTest {
@Autowired
private ClienteMapper mapper;
@Test
void deveLocalizarPorEnderecoEletronico() {
String emailTeste = "maria.silva@empresa.com";
Cliente resultado = mapper.localizarPorEmail(emailTeste);
assertThat(resultado).isNotNull();
assertThat(resultado.getEnderecoEletronico()).isEqualTo(emailTeste);
}
}
A escolha entre anotações e XML depende da complexidade: anotações para operações simples, XML para consultas dinâmicas com <where>, <choose> ou <foreach>.