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
目录
相关文章
|
2月前
|
NoSQL Redis
Redis的数据淘汰策略有哪些 ?
Redis 提供了 8 种数据淘汰策略,分为淘汰易失数据和淘汰全库数据两大类。易失数据淘汰策略包括:volatile-lru、volatile-lfu、volatile-ttl 和 volatile-random;全库数据淘汰策略包括:allkeys-lru、allkeys-lfu 和 allkeys-random。此外,还有 no-eviction 策略,禁止驱逐数据,当内存不足时新写入操作会报错。
183 16
|
17天前
|
缓存 NoSQL Redis
Redis经典问题:数据并发竞争
数据并发竞争是大流量系统(如火车票系统、微博平台)中常见的问题,可能导致用户体验下降甚至系统崩溃。本文介绍了两种解决方案:1) 加写回操作加互斥锁,查询失败快速返回默认值;2) 保持多个缓存备份,减少并发竞争概率。通过实践案例展示,成功提高了系统的稳定性和性能。
|
17天前
|
缓存 监控 NoSQL
Redis经典问题:数据不一致
在使用Redis时,缓存与数据库数据不一致会导致应用异常。主要原因包括缓存更新失败、Rehash异常等。解决方案有:重试机制、缩短缓存时间、优化写入策略、建立监控报警、定期验证一致性、采用缓存分层及数据回滚恢复机制。这些措施可确保数据最终一致性,提升应用稳定性和性能。
|
1月前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
121 5
|
1月前
|
缓存 NoSQL Java
Spring Boot中的分布式缓存方案
Spring Boot提供了简便的方式来集成和使用分布式缓存。通过Redis和Memcached等缓存方案,可以显著提升应用的性能和扩展性。合理配置和优化缓存策略,可以有效避免常见的缓存问题,保证系统的稳定性和高效运行。
51 3
|
1月前
|
缓存 Java 数据库连接
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
68 4
|
2月前
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
在项目中,为了解决Redis与Mysql的数据一致性问题,我们采用了多种策略:对于低一致性要求的数据,不做特别处理;时效性数据通过设置缓存过期时间来减少不一致风险;高一致性但时效性要求不高的数据,利用MQ异步同步确保最终一致性;而对一致性和时效性都有高要求的数据,则采用分布式事务(如Seata TCC模式)来保障。
75 14
|
2月前
|
存储 NoSQL 算法
Redis分片集群中数据是怎么存储和读取的 ?
Redis集群采用哈希槽分区算法,共有16384个哈希槽,每个槽分配到不同的Redis节点上。数据操作时,通过CRC16算法对key计算并取模,确定其所属的槽和对应的节点,从而实现高效的数据存取。
62 13
|
2月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
47 5
|
2月前
|
存储 NoSQL Redis
Redis的数据过期策略有哪些 ?
Redis 采用两种过期键删除策略:惰性删除和定期删除。惰性删除在读取键时检查是否过期并删除,对 CPU 友好但可能积压大量过期键。定期删除则定时抽样检查并删除过期键,对内存更友好。默认每秒扫描 10 次,每次检查 20 个键,若超过 25% 过期则继续检查,单次最大执行时间 25ms。两者结合使用以平衡性能和资源占用。
56 11
下一篇
开通oss服务