Persistência de Dados com MyBatis em Java

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:

  1. 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.
  2. 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/>.

Tags: MyBatis java SQL ORM Database-Persistence

Publicado em 7-11 01:46