- Configuração do Arquivo pom.xml
Para integrar o Spring Boot com o Redis, adicione as seguintes dependências ao seu arquivo pom.xml. Isso inclui o starter para Redis, além de bibliotecas auxiliares como Lombok e MyBatis-Plus para persistência de dados.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
- Classe de Configuração do Redis
Crie uma classe de configuração para definir o RedisTemplate e o CacheManager, habilitando o cache e configurando a serialização JSON para evitar problemas de codificação.
package com.exemplo.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@EnableCaching
@Configuration
public class ConfiguracaoRedis {
@Bean
public RedisTemplate<String, Object> criarTemplateRedis(RedisConnectionFactory conexao) {
RedisTemplate<String, Object> templateRedis = new RedisTemplate<>();
StringRedisSerializer serializadorString = new StringRedisSerializer();
Jackson2JsonRedisSerializer<Object> serializadorJson = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapeadorObjetos = new ObjectMapper();
mapeadorObjetos.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapeadorObjetos.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializadorJson.setObjectMapper(mapeadorObjetos);
templateRedis.setConnectionFactory(conexao);
templateRedis.setKeySerializer(serializadorString);
templateRedis.setValueSerializer(serializadorJson);
templateRedis.setHashValueSerializer(serializadorJson);
return templateRedis;
}
@Bean
public CacheManager gerenciadorCache(RedisConnectionFactory conexao) {
StringRedisSerializer serializadorChave = new StringRedisSerializer();
Jackson2JsonRedisSerializer<Object> serializadorValor = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapeador = new ObjectMapper();
mapeador.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapeador.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializadorValor.setObjectMapper(mapeador);
RedisCacheConfiguration configuracao = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(60000))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(serializadorChave))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializadorValor))
.disableCachingNullValues();
return RedisCacheManager.builder(conexao)
.cacheDefaults(configuracao)
.build();
}
}
- Propriedades da Aplicação
Configure as propriedades de conexão com o Redis e o banco de dados MySQL no arquivo application.properties, incluindo ajustes de formatação JSON e MyBatis-Plus.
spring.redis.host=192.168.44.64
spring.redis.password=123456
spring.redis.database=5
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/banco_dados?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=usuario
spring.datasource.password=senha
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.jackson.serialization.write-date-keys-as-timestamps=false
spring.main.allow-circular-references=true
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.mapper-locations=classpath:/mapper/*.xml
mybatis-plus.global-config.db-config.logic-not-delete-value=0
mybatis-plus.global-config.db-config.logic-delete-value=1
- Camada de Entidades
Defina as classes de entidade para representar os dados. Utilize o Lombok para simplificar o código com anotações como @Data.
package com.exemplo.entidade;
import lombok.Data;
@Data
public class Aluno {
private Integer id;
private String nome;
private Turma turma;
}
package com.exemplo.entidade;
import lombok.Data;
import java.util.List;
@Data
public class Turma {
private Integer id;
private String nome;
private List<Aluno> alunos;
}
- Camada de Mapper
Crie interfaces de mapper e arquivos XML para consultas ao banco de dados, utilizando MyBatis-Plus para mapeamento de objetos relacionais.
package com.exemplo.mapper;
import com.exemplo.entidade.Turma;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface TurmaMapper {
List<Turma> listarTodas();
}
<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="com.exemplo.mapper.TurmaMapper">
<resultMap id="mapaTurma" type="com.exemplo.entidade.Turma">
<id property="id" column="id_turma"/>
<result property="nome" column="nome_turma"/>
<collection property="alunos" ofType="com.exemplo.entidade.Aluno" autoMapping="true">
<id property="id" column="id_aluno"/>
<result property="nome" column="nome_aluno"/>
</collection>
</resultMap>
<select id="listarTodas" resultMap="mapaTurma">
SELECT t.id AS id_turma, t.nome AS nome_turma, a.id AS id_aluno, a.nome AS nome_aluno
FROM turma t LEFT JOIN aluno a ON t.id = a.turma_id
</select>
</mapper>
- Camada de Serviço
Implemente a lógica de serviço, utilizando anotações de cache para otimizar o desempenho. O método de paginação recupera dados do cache e aplica a filtragem.
package com.exemplo.servico;
import com.exemplo.entidade.Turma;
import java.util.List;
public interface ServicoTurma {
List<Turma> obterTodas();
List<Turma> obterPaginado(int pagina, int tamanho);
}
package com.exemplo.servico.impl;
import com.exemplo.entidade.Turma;
import com.exemplo.mapper.TurmaMapper;
import com.exemplo.servico.ServicoTurma;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class ServicoTurmaImpl implements ServicoTurma {
@Resource
private TurmaMapper turmaMapper;
@Override
@Cacheable(value = "cacheTurma", key = "'todas'")
public List<Turma> obterTodas() {
return turmaMapper.listarTodas();
}
@Override
public List<Turma> obterPaginado(int pagina, int tamanho) {
List<Turma> todasTurmas = obterTodas();
return todasTurmas.stream()
.skip((long) (pagina - 1) * tamanho)
.limit(tamanho)
.collect(Collectors.toList());
}
}
- Camada de Controlador
Crie endpoints REST para expor os serviços, permitindo a recuperação de dados com opções de paginação.
package com.exemplo.controlador;
import com.exemplo.entidade.Turma;
import com.exemplo.servico.ServicoTurma;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/turmas")
public class ControladorTurma {
@Resource
private ServicoTurma servicoTurma;
@GetMapping("/listar")
public List<Turma> listarTodas() {
return servicoTurma.obterTodas();
}
@GetMapping("/paginar")
public List<Turma> listarPaginado(@RequestParam int pagina, @RequestParam int tamanho) {
return servicoTurma.obterPaginado(pagina, tamanho);
}
}