Boas Práticas na Estrutura de Diretórios e Configuração do MyBatis

A organização eficiente de um projeto MyBatis é fundamental para garantir a escalabilidade e facilitar a manutenção do código. Ao separar as configurações de banco de dados, os mapeamentos SQL e as classes Java, criamos um ambiente de desenvolvimento mais limpo e profissional.

Organização de Recursos e Configuração

Dentro do diretório src/main/resources, é recomendável agrupar os arquivos relacionados ao MyBatis em uma subpasta dedicada. Isso evita que as configurações se misturem com outros componentes do sistema. Dividimos a configuração em duas partes principais:

  • Configuração Global (mybatis-config.xml): Define o ambiente, o gerenciamento de transações, o pool de conexões e os caminhos dos arquivos de mapeamento.
  • Arquivos de Mapeamento (Mappers): Contêm as instruções SQL específicas da aplicação.

Veja um exemplo de como estruturar o mybatis-config.xml dentro de resources/mybatis/config/:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/db_exemplo?useSSL=false&amp;serverTimezone=UTC"/>
                <property name="username" value="usuario_app"/>
                <property name="password" value="senha_segura"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mybatis/mapper/UsuarioMapper.xml"/>
    </mappers>
</configuration>

O arquivo de mapeamento SQL (UsuarioMapper.xml) define a relação entre os comandos do banco de dados e os métodos Java. O namespace deve corresponder exatamente ao pacote e nome da interface do Mapper correspondente.

<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="br.com.projeto.mapper.UsuarioMapper">
    <select id="listarTodos" resultType="br.com.projeto.model.Usuario">
        SELECT * FROM usuarios
    </select>
    <select id="buscarPorId" resultType="br.com.projeto.model.Usuario">
        SELECT * FROM usuarios WHERE id_usuario = #{id}
    </select>
</mapper>

Estrutura de Classes Java

Para interagir com o MyBatis de forma tipada, utilizamos dois componentes principais no código Java:

1. O Modelo de Dados (POJO)

Representa a entidade do banco de dados. É uma classe simples com atributos privados e métodos de acesso.

package br.com.projeto.model;

public class Usuario {
    private int idUsuario;

    public int getIdUsuario() {
        return idUsuario;
    }

    public void setIdUsuario(int idUsuario) {
        this.idUsuario = idUsuario;
    }
}

2. A Interface Mapper

Esta interface atua como a ponte entre o Java e o XML. O MyBatis gera dinamicamente a implementação desta interface em tempo de execução.

package br.com.projeto.mapper;

import br.com.projeto.model.Usuario;
import java.util.List;

public interface UsuarioMapper {
    List<Usuario> buscarPorId(int id);
    List<Usuario> listarTodos();
}

Implementação de Testes Unitários

A melhor forma de validar a persistência é através de testes integrados. Utilizadno o JUnit, podemos configurar um ambiente que inicializa o SqlSessionFactory e executa operações de teste. Em vez de chamar os métodos via strings, utilizamos o método getMapper, que é mais seguro e fácil de refatorar.

package br.com.projeto;

import br.com.projeto.mapper.UsuarioMapper;
import br.com.projeto.model.Usuario;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UsuarioPersistenceTest {
    private static SqlSessionFactory sessionFactory;

    @BeforeAll
    static void setup() throws IOException {
        InputStream config = Resources.getResourceAsStream("mybatis/config/mybatis-config.xml");
        sessionFactory = new SqlSessionFactoryBuilder().build(config);
    }

    @Test
    void deveBuscarUsuarioPorId() {
        try (SqlSession session = sessionFactory.openSession()) {
            UsuarioMapper mapper = session.getMapper(UsuarioMapper.class);
            List<Usuario> resultado = mapper.buscarPorId(10);
            
            if (resultado != null) {
                resultado.forEach(u -> System.out.println("ID Localizado: " + u.getIdUsuario()));
            }
        }
    }

    @Test
    void deveListarTodosUsuarios() {
        try (SqlSession session = sessionFactory.openSession()) {
            List<Usuario> usuarios = session.selectList("br.com.projeto.mapper.UsuarioMapper.listarTodos");
            usuarios.forEach(u -> System.out.println("Usuário: " + u.getIdUsuario()));
        }
    }
}

Essa estrutura modularizada permite que o projeto cresça de forma organizada. A separação clara entre a lógica de negócio (Java) e a lógica de persistência (XML/SQL) facilita a depuração e a colaboração em equipe.

Tags: MyBatis java SQL JUnit DesignPatterns

Publicado em 9-14 10:42