spring-boot | 整合Redis缓存数据

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: spring boot 整合redis非常简单,首先创建spring boot的Maven项目,然后在pom.xml文件中引入redis的依赖。引入redis的依赖 org.springframework.boot spring-boot-starter-data-redis添加redis的配置文件在application.properties里面设置redis的配置文件,spring boot会自动加载redis的配置文件,非常方便。

spring boot 整合redis非常简单,首先创建spring boot的Maven项目,然后在pom.xml文件中引入redis的依赖。

引入redis的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

添加redis的配置文件

在application.properties里面设置redis的配置文件,spring boot会自动加载redis的配置文件,非常方便。

#redsi配置
# Redis数据库索引(默认为0) 
spring.redis.database=2 
# Redis服务器地址 
spring.redis.host=localhost
# Redis服务器连接端口 
spring.redis.port=6379 
# Redis服务器连接密码(默认为空) 
spring.redis.password= 123456
#连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8 
# 连接池最大阻塞等待时间(使用负值表示没有限制) 
spring.redis.pool.max-wait=-1 
# 连接池中的最大空闲连接 
spring.redis.pool.max-idle=8 
# 连接池中的最小空闲连接 
spring.redis.pool.min-idle=0 
# 连接超时时间(毫秒) 
spring.redis.timeout=0

缓存的的配置

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {
    
    @Value("${spring.redis.host}")
    private String host;
    
    @Value("${spring.redis.port}")
    private int port;
    
    @Value("${spring.redis.timeout}")
    private int timeout;
    
    @Value("${spring.redis.database}")
    private int database;
    
    @Value("${spring.redis.password}")
    private String password;
    /**
     * 键的生成策略
     * @return
     */
    @Bean
    public KeyGenerator wiselyKeyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setHostName(host);
        factory.setPort(port);
        factory.setTimeout(timeout);
        factory.setPassword(password);
        factory.setDatabase(database);
        return factory;
    }

    /**
     * 配置CacheManager 管理cache
     * @param redisTemplate
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); 
        cacheManager.setDefaultExpiration(60*60); // 设置key-value超时时间
        return cacheManager;
    }

    
    
    @Bean
       public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
          RedisTemplate<Object, Object> template = new RedisTemplate<>();
          template.setConnectionFactory(connectionFactory);

          //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
          Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

          ObjectMapper mapper = new ObjectMapper();
          mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
          mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
          serializer.setObjectMapper(mapper);

          template.setValueSerializer(serializer);
          //使用StringRedisSerializer来序列化和反序列化redis的key值
          template.setKeySerializer(new StringRedisSerializer());
          template.afterPropertiesSet();
          return template;
       }
}

单元测试


@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest {
    
    
     @Autowired
     private RedisTemplate<Object, Object> redisTemplate;
     
    @Test
    public void RedisTests(){
        
        try {
            redisTemplate.opsForValue().set("name", "张三");
            Object object = redisTemplate.opsForValue().get("name");
            System.out.println(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

测试结果如下,name已经被成功存储到redis中.控制台成功打印出张三。



再通过redis客户端查看,发现数据已经被存储。到这里,spring boot结合reids已经整合完毕。



数据缓存

对应实体类,因为之前我们已经进行过序列化配置,所以这里无需再实现序列化接口。

@Table(name = "city")
public class City implements Serializable{
    private static final long serialVersionUID = 1L;
    @Id
    private String id;
    private String name;
    private String state;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

利用注解的方式进行缓存

/**
     * @Cacheable 
     * 应用到读取数据的方法上,先从缓存中读取,如果没有再从DB获取数据,然后把数据添加到缓存中
     * unless 表示条件表达式成立的话不放入缓存
     */
    @Override
    @Cacheable(value = "city" , keyGenerator = "wiselyKeyGenerator")
    public List<City> searchById(City id) {
        System.out.println("没有执行缓存");
        return cityDao.select(id);
    }

编写测试类并进行测试

发现第一次查询的是数据库,第二次直接从缓存中读取的数据。



再通过redis客户端发现数据已经被成功存储.


注意

缓存注解

缓存注解
缓存注解

条件缓存

条件缓存
条件缓存

@Cacheable
应用到读取数据的方法上,先从缓存中读取,如果没有再从DB获取数据,然后把数据添加到缓存中 。
unless 表示条件表达式成立的话不放入缓存。
主要参数:

@CacheEvict
应用到删除数据的方法上,调用方法时会从缓存中删除对应key的数据。
@CachePut
应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存。

(完)


参考文章

Spring Boot with Redis
Spring思维导图,让Spring不再难懂(cache篇)

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
11天前
|
监控 NoSQL Java
场景题:百万数据插入Redis有哪些实现方案?
场景题:百万数据插入Redis有哪些实现方案?
32 1
场景题:百万数据插入Redis有哪些实现方案?
|
22天前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
56 6
|
2天前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
21 10
|
2天前
|
缓存 监控 NoSQL
Redis 缓存穿透的检测方法与分析
【10月更文挑战第23天】通过以上对 Redis 缓存穿透检测方法的深入探讨,我们对如何及时发现和处理这一问题有了更全面的认识。在实际应用中,我们需要综合运用多种检测手段,并结合业务场景和实际情况进行分析,以确保能够准确、及时地检测到缓存穿透现象,并采取有效的措施加以解决。同时,要不断优化和改进检测方法,提高检测的准确性和效率,为系统的稳定运行提供有力保障。
20 5
|
2天前
|
缓存 监控 NoSQL
Redis 缓存穿透及其应对策略
【10月更文挑战第23天】通过以上对 Redis 缓存穿透的详细阐述,我们对这一问题有了更深入的理解。在实际应用中,我们需要根据具体情况综合运用多种方法来解决缓存穿透问题,以保障系统的稳定运行和高效性能。同时,要不断关注技术的发展和变化,及时调整策略,以应对不断出现的新挑战。
17 4
|
4天前
|
缓存 NoSQL Java
有Redis为什么还要本地缓存?谈谈你对本地缓存的理解?
有Redis为什么还要本地缓存?谈谈你对本地缓存的理解?
13 0
有Redis为什么还要本地缓存?谈谈你对本地缓存的理解?
|
11天前
|
缓存 NoSQL Java
Spring Boot与Redis:整合与实战
【10月更文挑战第15天】本文介绍了如何在Spring Boot项目中整合Redis,通过一个电商商品推荐系统的案例,详细展示了从添加依赖、配置连接信息到创建配置类的具体步骤。实战部分演示了如何利用Redis缓存提高系统响应速度,减少数据库访问压力,从而提升用户体验。
32 2
|
17天前
|
缓存 监控 前端开发
处理页面缓存中数据不一致的问题
【10月更文挑战第9天】
30 2
|
11天前
|
存储 数据采集 监控
将百万数据插入到 Redis,有哪些实现方案
【10月更文挑战第15天】将百万数据插入到 Redis 是一个具有挑战性的任务,但通过合理选择实现方案和进行性能优化,可以高效地完成任务。
44 0
|
6月前
|
XML 安全 Java
深入实践springboot实战 蓄势待发 我不是雷锋 我是知识搬运工
springboot,说白了就是一个集合了功能的大类库,包括springMVC,spring,spring data,spring security等等,并且提供了很多和可以和其他常用框架,插件完美整合的接口(只能说是一些常用框架,基本在github上能排上名次的都有完美整合,但如果是自己写的一个框架就无法实现快速整合)。