O MyBatis é um framework de persistência de alto desempenho que facilita a integração entre aplicações Java e bancos de dados relacionais. Diferente de ORMs completos que ocultam o SQL, o MyBatis permite o controle total sobre as queries, eliminando a maior parte do código manual de JDBC e a configuração repetitiva de parâmetros e conjuntos de resultados.
Configuração de Dependência
Para iniciar o uso do MyBatis em um projeto Maven, adicione a seguinte dependência ao seu arquivo pom.xml:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
Entendendo a Persistência
Persistência refere-se ao mecanismo de converter dados entre o estado volátil (na memória da aplicação) e o estado duradouro (no banco de dados). O MyBatis atua como uma ponte flexível para essa transição, garantindo que a lógica de negócio permaneça separada da lógica de acesso aos dados.
Vantagens da Utilização
- Flexibilidade: O SQL é escrito em arquivos XML separados, facilitando a otimização e manutenção.
- Desacoplamento: Separação clara entre a camada DAO e a lógica de negócios.
- Simplicidade: Reduz drasticamente o boilerplate de códigos JDBC tradicionais.
- SQL Dinâmico: Capacidade robusta de construir queries complexas baseadas em condições lógicas.
Configuração do Ambiente
O arquivo central de configuração define as propriedades do banco de dados e o comportamento do framework:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<environments default="prod">
<environment id="prod">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db_app?useSSL=false"/>
<property name="username" value="admin"/>
<property name="password" value="senha123"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/AccountMapper.xml"/>
</mappers>
</configuration>
Classe Utilitária de Sessão
É recomendável criar uma classe para gerenciar o SqlSessionFactory, garantindo o padrão Snigleton para a fábrica de sessões:
public class DbConnector {
private static SqlSessionFactory sessionFactory;
static {
try {
String cfg = "mybatis-config.xml";
InputStream stream = Resources.getResourceAsStream(cfg);
sessionFactory = new SqlSessionFactoryBuilder().build(stream);
} catch (IOException e) {
throw new RuntimeException("Erro ao iniciar MyBatis", e);
}
}
public static SqlSession openSession() {
return sessionFactory.openSession();
}
}
Operações CRUD e Mapeamento
O mapeamento entre a interface Java e o SQL é feito via XML. Veja um exemplo para uma entidade de conta de usuário:
<mapper namespace="com.app.dao.AccountMapper">
<!-- Buscar todos -->
<select id="findAll" resultType="com.app.model.Account">
SELECT id, username, email FROM accounts
</select>
<!-- Inserir novo -->
<insert id="save" parameterType="com.app.model.Account">
INSERT INTO accounts (username, email) VALUES (#{username}, #{email})
</insert>
<!-- Atualizar -->
<update id="modify" parameterType="com.app.model.Account">
UPDATE accounts SET email = #{email} WHERE id = #{id}
</update>
<!-- Deletar -->
<delete id="remove">
DELETE FROM accounts WHERE id = #{id}
</delete>
</mapper>
Tratando Divergências com ResultMap
Quando os nomes das colunas no banco não coincidem com os atributos da classe Java, utilizamos o resultMap:
<resultMap id="accountResult" type="Account">
<id column="acc_id" property="id"/>
<result column="acc_name" property="username"/>
</resultMap>
<select id="getById" resultMap="accountResult">
SELECT acc_id, acc_name FROM accounts WHERE acc_id = #{id}
</select>
SQL Dinâmico
O MyBatis brilha ao lidar com filtros opcionais. O elemento <if> permite incluir fragmentos de SQL apenas se os parâmetros forem fornecidos:
<select id="searchAccounts" resultType="Account">
SELECT * FROM accounts
<where>
<if test="username != null">
AND username LIKE #{username}
</if>
<if test="email != null">
AND email = #{email}
</if>
</where>
</select>
Ciclo de Vida e Escopo
- SqlSessionFactoryBuilder: Deve ser descartado após a criação da Factory.
- SqlSessionFactory: Deve existir durante toda a execução da aplicação (escopo de aplicação).
- SqlSession: Representa uma unidade de trabalho. Deve ser aberta e fechada em cada requisição ou método (não é thread-safe).
Sistema de Cache
O framework oferece dois níveis de cache:
- Cache de Primeiro Nível: Habilitado por padrão no escopo da
SqlSession. Garante que a mesma query na mesma sessão não atinja o banco duas vezes. - Cache de Segundo Nível: Escopo por namespace. Deve ser habilitado nas configurações globais e no arquivo mapper específico através da tag
<cache/>.