前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >springboot高级特性-redis作为缓存

springboot高级特性-redis作为缓存

作者头像
暴躁的程序猿
发布2022-03-23 17:28:42
3590
发布2022-03-23 17:28:42
举报

springboot版本为2.5.4 redis版本 3.2 引入starter

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置redis

代码语言:javascript
复制
spring.redis.port=6379
spring.redis.host=localhost

导入依赖之后会在容器中为我们注入两个template帮助我们操作redis

一个是StringRedisTemplate (操做字符串的)和 RedisTemplate

使用的时候直接注入即可

常见的几个方法

代码语言:javascript
复制
字符串String list  set  zset  hash
opsForValue() 操作字符串的
opsForList()操作list
opsForSet()操作set的
opsForHash()操作hash
opsForZset() 操作zset的  有序集合

测试redis是否连接成功

代码语言:javascript
复制
@SpringBootTest
class Springboot01CacheApplicationTests {

    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    /**
     * 字符串String list  set  zset  hash
     * opsForValue() 操作字符串的
     * opsForList()操作list
     * opsForSet()操作set的
     * opsForHash()操作hash
     * opsForZset() 操作zset的  有序集合
     */
    public void test01(){
        //往redis中保存数据
        stringRedisTemplate.opsForValue().set("message","abc");
    }

}

测试结果

在这里插入图片描述
在这里插入图片描述

测试redis序列化对象

因为我们存储对象到redis时 redis默认的是jdk序列化方式 与我们想要的json等格式有一些区别 所以我们 需要自己指定redis的序列化方式 我们 创建一个配置类 设置 redis的序列化器

代码语言:javascript
复制
@Configuration
public class MyRedisConfig {

    @Bean
    public RedisTemplate<String, Employee> myRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate<String, Employee> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);

        // 设置value的序列化规则和 key的序列化规则
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();

        return template;
    }
}

测试

代码语言:javascript
复制
 @Test
    public void test02(){
        Employee empById = employeeMapper.getEmpById(1);
        System.out.println(empById);
        myRedisTemplate.opsForValue().set("emp",empById);
        Employee emp = myRedisTemplate.opsForValue().get("emp");
        System.out.println(emp);
    }

数据库中的数据

在这里插入图片描述
在这里插入图片描述

整合缓存

boot中的CacheManager缓存管理器 帮我们创建缓存组件 缓存组件实际为我们缓存数据

当我们引入了redis Starter后 会在我们容器中放入一个 RedisCacheManager 缓存管理器 这时我们默认的SimpleCacheConfiguration就会失效 因为 SimpleCacheConfiguration的判断条件是缓存中没有CacheManager的情况下生效 我们的Redis放入了一个 RedisCacheManager 就会让我们的SimpleCache失效

ReidsCacheManager帮我们创建RedisCache来作为缓存组件 RedisCache通过操作redis缓存数据

所以说我们直接测试就可以了

我们的pojo类 注意实现Serializable 接口 不然不能序列化

代码语言:javascript
复制
@Data
public class Employee implements Serializable {
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;  //性别  1男  0女
}

mapper

代码语言:javascript
复制
@Mapper
public interface EmployeeMapper {

    @Select("select * from employee where id =#{id}")
    public Employee getEmpById(Integer id);

    @Select("select * from employee where lastName=#{lastName}")
    public Employee getEmpByLastName(String lastName);
}

service 在service层配置缓存注解 使用缓存注解需要在启动类上加@@EnableCaching

代码语言:javascript
复制
@CacheConfig(cacheNames = "emp")
@Service
public class EmployeeService {

    @Autowired
    EmployeeMapper employeeMapper;

    @Cacheable(cacheNames = "emp",condition = "#id>0")
    public Employee getEmp(Integer id){
        System.out.println("查询"+id+"号员工");
        Employee empById = employeeMapper.getEmpById(id);
        return empById;
    }

}

controller

代码语言:javascript
复制
@RestController
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @GetMapping("/emp/{id}")
    public Employee getEmployee(@PathVariable("id")Integer id){
        Employee emp = employeeService.getEmp(id);
        return emp;
    }
}

我们先进行第一次查询数据

代码语言:javascript
复制
访问http://localhost:8080/emp/1  

我们发现访问了数据库

在这里插入图片描述
在这里插入图片描述

这时候我们清空控制台再进行一次访问发现没有查询数据库 肯定是redis帮我们缓存起来了

在这里插入图片描述
在这里插入图片描述

这是候我们查看redis发现多了一个缓存数据

在这里插入图片描述
在这里插入图片描述

我们取出数据看看

代码语言:javascript
复制
127.0.0.1:6379> get emp::1
代码语言:javascript
复制
"\xac\xed\x00\x05sr\x00\x1bcom.rpf.cache.bean.EmployeePU2z\x98\xeat\xc9\x02\x00\x05L\x00\x03dIdt\x00\x13Ljava/lang/Integer;L\x00\x05emailt\x00\x12Ljava/lang/String;L\x00\x06genderq\x00~\x00\x01L\x00\x02idq\x00~\x00\x01L\x00\blastNameq\x00~\x00\x02xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01t\x00\x0e2858458@qq.comq\x00~\x00\x06q\x00~\x00\x06t\x00\x06\xe7\x8e\x8b\xe4\xba\x94"

发现使用序列化的方式保存的 默认保存数据 k-v都是Object 的时候;利用序列化来保存的 我们需要更改CacheManager 使用Json的方式缓存

在配置类中添加配置

代码语言:javascript
复制
@Configuration
public class MyRedisConfig {

    //配置Redistemplate
   @Bean
    public RedisTemplate<String, Object> myRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);


        // 设置value的序列化规则和 key的序列化规则
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();

        return template;
    }

    //使用CacheManager缓存
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(om.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // 配置序列化(解决乱码的问题),过期时间30秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(1800000))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

配置完成重新测试

发现缓存成功

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

redis中以json格式缓存了值

在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-09-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档