Preparação do Banco de Dados
Para iniciar, definiremos a estrutura da tabela usuario e popularemos com alguns dados iniciais para fundamentar as operações subsequentes.
DROP TABLE IF EXISTS usuario;
CREATE TABLE `usuario` (
`id_usuario` bigint NOT NULL AUTO_INCREMENT COMMENT 'Chave primária',
`nome` varchar(50) DEFAULT NULL COMMENT 'Nome completo',
`idade` int DEFAULT NULL COMMENT 'Idade',
`email` varchar(100) DEFAULT NULL COMMENT 'Endereço de e-mail',
`status_exclusao` tinyint NOT NULL DEFAULT '0' COMMENT 'Indicador de exclusão lógica',
PRIMARY KEY (`id_usuario`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO usuario (nome, idade, email, status_exclusao) VALUES
('Ana Silva', 25, 'ana.silva@exemplo.com', 0),
('Bruno Costa', 30, 'bruno.costa@exemplo.com', 0),
('Carla Souza', 22, 'carla.souza@exemplo.com', 0),
('Diego Lima', 28, 'diego.lima@exemplo.com', 0),
('Elena Rocha', 35, 'elena.rocha@exemplo.com', 0);
Dependências do Projeto
Adicione as seguintes dependências ao seu arquivo pom.xml. Estamos utilizando o HikariCP como pool de conexões padrão e a versão mais recente do conector MySQL.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Configuração da Aplicação
Defina as propriedades de conexão com o banco de dados e ative o log de instruções SQL no arquivo application.yml.
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_exemplo?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username: root
password: sua_senha_segura
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
Na classe principal do Spring Boot, configure a varredura dos mappers:
@SpringBootApplication
@MapperScan("br.com.exemplo.mybatisplus.mapper")
public class MyBatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MyBatisPlusApplication.class, args);
}
}
Definição da Entidade e Mapper
Crie a classe de entdiade mapeando os campos para as colunas do banco de dados.
package br.com.exemplo.mybatisplus.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
@TableName("usuario")
public class Usuario {
@TableId(value = "id_usuario", type = IdType.AUTO)
private Long idUsuario;
private String nome;
private Integer idade;
private String email;
@TableLogic(value = "0", delval = "1")
private Integer statusExclusao;
// Construtores, Getters, Setters e toString() omitidos para brevidade
}
Em seguida, declare a interface do Mapper estendendo o BaseMapper:
package br.com.exemplo.mybatisplus.mapper;
import br.com.exemplo.mybatisplus.entity.Usuario;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UsuarioMapper extends BaseMapper<Usuario> {
}
Teste de Inserção e Consulta Básica
@SpringBootTest
class UsuarioMapperTest {
@Autowired
private UsuarioMapper usuarioMapper;
@Test
void testarInsercaoEListagem() {
Usuario novoUsuario = new Usuario();
novoUsuario.setNome("Fernanda Dias");
novoUsuario.setIdade(27);
novoUsuario.setEmail("fernanda.dias@exemplo.com");
usuarioMapper.insert(novoUsuario);
List<Usuario> usuarios = usuarioMapper.selectList(null);
usuarios.forEach(System.out::println);
}
}
Camada de Serviço e Operações em Lote
Para operações mais complexas e processamento em lote, utilize a camada de serviço fornecida pelo framework.
package br.com.exemplo.mybatisplus.service;
import br.com.exemplo.mybatisplus.entity.Usuario;
import com.baomidou.mybatisplus.extension.service.IService;
public interface UsuarioService extends IService<Usuario> {
}
package br.com.exemplo.mybatisplus.service.impl;
import br.com.exemplo.mybatisplus.entity.Usuario;
import br.com.exemplo.mybatisplus.mapper.UsuarioMapper;
import br.com.exemplo.mybatisplus.service.UsuarioService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class UsuarioServiceImpl extends ServiceImpl<UsuarioMapper, Usuario>
implements UsuarioService {
}
Exemplo de teste para inserção em lote:
@SpringBootTest
class UsuarioServiceTest {
@Autowired
private UsuarioService usuarioService;
@Test
void testarInsercaoEmLote() {
List<Usuario> listaUsuarios = List.of(
new Usuario("Gabriel Martins", 24, "gabriel@exemplo.com"),
new Usuario("Helena Barbosa", 29, "helena@exemplo.com")
);
usuarioService.saveBatch(listaUsuarios);
System.out.println(usuarioService.list());
}
}
Visão Geral dos Métodos do IService
A interface IService encapsula diversas operações CRUD. Abaixo estão as assinatruas dos métodos mais utilizados:
Inserção (Save)
// Insere um único registro
boolean save(T entity);
// Insere múltiplos registros em lote
boolean saveBatch(Collection<T> entityList);
// Insere em lote definindo o tamanho do lote
boolean saveBatch(Collection<T> entityList, int batchSize);
Inserção ou Atualização (SaveOrUpdate)
// Atualiza se o ID existir, caso contrário, insere
boolean saveOrUpdate(T entity);
// Tenta atualizar com base no Wrapper, se falhar, executa saveOrUpdate
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// Operação em lote para inserir ou atualizar
boolean saveOrUpdateBatch(Collection<T> entityList);
Remoção (Remove)
// Remove com base nas condições do Wrapper
boolean remove(Wrapper<T> queryWrapper);
// Remove pelo ID
boolean removeById(Serializable id);
// Remove em lote por uma coleção de IDs
boolean removeByIds(Collection<? extends Serializable> idList);
Atualização (Update)
// Atualiza com base no Wrapper
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// Atualiza pelo ID
boolean updateById(T entity);
// Atualiza em lote pelo ID
boolean updateBatchById(Collection<T> entityList);
Consulta (Get e List)
// Busca por ID
T getById(Serializable id);
// Busca um único registro com Wrapper
T getOne(Wrapper<T> queryWrapper);
// Lista todos os registros
List<T> list();
// Lista registros com base em condições
List<T> list(Wrapper<T> queryWrapper);
Paginação (Page)
// Consulta paginada sem condições
IPage<T> page(IPage<T> page);
// Consulta paginada com condições
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
Exclusão Lógica
A exclusão lógica pode ser configurada via anotação diretamente na entidade (como demonstrado na classe Usuario com @TableLogic) ou globalmente via arquivo de configuração:
mybatis-plus:
global-config:
db-config:
logic-delete-field: statusExclusao
logic-delete-value: 1
logic-not-delete-value: 0
Configuração do Plugin de Paginação
Para habilitar a paginação física, é necessário registrar o interceptor de paginação do MyBatis-Plus.
package br.com.exemplo.mybatisplus.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor interceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
Testando a paginação:
@Test
void testarPaginacao() {
Page<Usuario> pagina = new Page<>(1, 3);
Page<Usuario> resultado = usuarioMapper.selectPage(pagina, null);
resultado.getRecords().forEach(System.out::println);
System.out.println("Total de registros: " + resultado.getTotal());
}