十次方08、缓存处理-redis、spring cache

本文详细介绍如何利用Redis和Spring Data Redis优化文章查询性能,包括缓存处理、缓存过期及活动信息缓存实现,通过具体代码示例展示了缓存机制在微服务架构中的应用。

缓存处理

1 redis和SpringDataRedis

为了提高查询的性能,我们通常采用Redis缓存解决。

  1. Redis环境搭建
    我们以docker的形式搭建Redis 服务
docker run ‐di ‐‐name=tensquare_redis ‐p 6379:6379 redis
  1. SpringDataRedis
    Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作。

2 实现文章的缓存处理

2.1 查询文章操作缓存

  1. 在tensquare_article 的pom.xml引入依赖
    ......
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 修改application.yml ,在spring节点下添加配置
    spring: 
      ......
      redis:
        host: 192.168.1.194
    
  3. 修改ArticleService 引入RedisTemplate,并修改findById方法
    @Autowired
    private RedisTemplate redisTemplate;
    ......
    /**
    * 根据ID查询实体
    * @param id
    * @return
    */
    public Article findById(String id) {
    	//从缓存中提取
    	Article article=(Article)redisTemplate.opsForValue().get("article_"+id);
    	// 如果缓存没有则到数据库查询并放入缓存
    	if(article==null) {
    		article = articleDao.findById(id).get();
    		redisTemplate.opsForValue().set("article_" + id, article);
    	} 
    	return article;
    }
    
    这样在查询的时候,就会自动将文章放入缓存

2.2 修改或删除后清除缓存

......
	/**
	* 修改
	* @param article
	*/
	public void update(Article article) {
		redisTemplate.delete( "article_" + article.getId() );//删除缓存
		articleDao.save(article);
	} 
	/**
	* 删除
	* @param id
	*/
	public void deleteById(String id) {
		redisTemplate.delete( "article_" + id );//删除缓存
		articleDao.deleteById(id);
	}
......

2.3 缓存过期处理

修改findById方法 ,设置1天的过期时间

redisTemplate.opsForValue().set("article_" + id, article,1,TimeUnit.DAYS);

为了方便测试,我们可以把过期时间改为10秒,然后观察控制台输出

redisTemplate.opsForValue().set("article_" + id, article,10,TimeUnit.SECONDS);

测试接口,调用查,改,删的api,观察控制台输出的sql语句次数。

2.4 SpringDataRedis使用说明

stringRedisTemplate.opsForValue().set("test", "100",60*10,TimeUnit.SECONDS);//向redis里存入数据和设置缓存时间
stringRedisTemplate.opsForValue().get("test")//根据key获取缓存中的val
stringRedisTemplate.boundValueOps("test").increment(-1);//val做-1操作
stringRedisTemplate.boundValueOps("test").increment(1);//val +1
stringRedisTemplate.getExpire("test")//根据key获取过期时间
stringRedisTemplate.getExpire("test",TimeUnit.SECONDS)//根据key获取过期时间并换算成指定单位
stringRedisTemplate.delete("test");//根据key删除缓存
stringRedisTemplate.hasKey("546545");//检查key是否存在,返回boolean值
stringRedisTemplate.expire("red_123",1000 , TimeUnit.MILLISECONDS);//设置过期时间
stringRedisTemplate.opsForSet().add("red_123", "1","2","3");//向指定key中存放set集合
stringRedisTemplate.opsForSet().isMember("red_123", "1")//根据key查看集合中是否存在指定数据
stringRedisTemplate.opsForSet().members("red_123");//根据key获取set集合

3 Spring Cache处理活动信息的缓存

Spring Cache使用方法与Spring对事务管理的配置相似。Spring Cache的核心就是对某个方法进行缓存,其实质就是缓存该方法的返回结果,并把方法参数和结果用键值对的方式存放到缓存中,当再次调用该方法使用相应的参数时,就会直接从缓存里面取出指定的结果进行返回。
常用注解:

  • @Cacheable:使用这个注解的方法在执行后会缓存其返回结果。
  • @CacheEvict:使用这个注解的方法在其执行前或执行后移除Spring Cache中的某些
    元素。

3.1 活动子模块代码生成

  1. 使用代码生成器生成招聘微服务代码 tensquare_gathering
  2. 拷贝到当前工程,并在父工程引入。
  3. 修改Application类名称为GatheringApplication
  4. 修改application.yml 中的端口为9005 ,url 为jdbc:mysql://192.168.184.134:3306/tensquare_gathering?characterEncoding=UTF8
  5. 进行浏览器测试
  6. 给service加上事务注解@Transactional
  7. 修改BaseExceptionHandler的注解@ControllerAdvice改为@RestControllerAdvice,去掉方法上的@ResponseBody

3.2 活动详情的缓存实现

步骤:

  1. 我们在tensquare_gathering的pom.xml中引入SpringDataRedis
    ......
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 修改application.yml ,在spring节点下添加配置
    spring: 
      ......
      redis:
        host: 192.168.1.194
    
  3. 为GatheringApplication添加@EnableCaching开启缓存支持
    @SpringBootApplication
    @EnableCaching
    public class GatheringApplication {......}
    
  4. 在GatheringService的findById方法添加缓存注解,这样当此方法第一次运行,在缓存中没有找到对应的value和key,则将查询结果放入缓存。
    ......
    	/**
    	* 根据ID查询实体
    	* @param id
    	* @return
    	*/
    	@Cacheable(value="gathering",key="#id")
    	public Gathering findById(String id) {
    		return gatheringDao.findById(id).get();
    	}
    ......
    
  5. 当我们对数据进行删改的时候,需要更新缓存。其实更新缓存也就是清除缓存,因为清除缓存后,用户再次调用查询方法无法提取缓存会重新查找数据库中的记录并放入缓存。
    在GatheringService的update、deleteById方法上添加清除缓存的注解。
    ......
    	/**
    	* 修改
    	* @param gathering
    	*/
    	@CacheEvict(value="gathering",key="#gathering.id")
    	public void update(Gathering gathering) {
    		gatheringDao.save(gathering);
    	} 
    	/**
    	* 删除
    	* @param id
    	*/
    	@CacheEvict(value="gathering",key="#id")
    	public void deleteById(String id) {
    		gatheringDao.deleteById(id);
    	}
    ......
    

十次方00、总目录
https://blog.youkuaiyun.com/amingccc/article/details/84260613

### spring-boot-starter-data-redisspring-boot-starter-cache 的区别及应用场景 #### 区别 `spring-boot-starter-data-Redis` 主要用于与 Redis 数据库交互,提供了一套完整的操作 Redis 的 API 支持[^1]。它不仅限于缓存场景,还可以作为消息队列、发布/订阅模式等多种用途的数据存储解决案。 而 `spring-boot-starter-cache` 则专注于实现应用级别的缓存抽象层,旨在简化开发者在项目中加入缓存机制的过程[^2]。此模块并不直接关联任何特定类型的持久化技术;相反,它是通过 SPI (Service Provider Interface) 来支持多种不同的缓存提供商,比如 EhCache, Caffeine 或者 Redis 等。 因此,在引入 `spring-boot-starter-cache` 后还需要额外指定具体的缓存实现式——如果选择了 Redis,则通常会配合使用 `spring-boot-starter-data-redis` 提供的支持来完成实际的操作逻辑[^4]。 #### 应用场景 对于希望利用 Redis 进行复杂数据结构管理和分布式环境下的高性能读写需求的应用来说,应该优先考虑采用 `spring-boot-starter-data-redis` 。这使得开发人员能够充分利用 Redis 所提供的诸如列表(lists),集合(sets), 排序集(sorted sets)等功能特性[^3]。 另一面,当只需要简单地提升热点查询效率或是减少数据库负载压力时,可以选择仅使用 `spring-boot-starter-cache` 并搭配合适的本地或远程缓存案即可满足业务要求。这种式下,即使不涉及复杂的键值对操作也能有效改善系统的响应时间和吞吐量表现。 ```java // 使用 spring-boot-starter-data-redis 实现简单的字符串设置和获取 @Autowired private StringRedisTemplate stringRedisTemplate; public void setKeyValue(String key, String value){ stringRedisTemplate.opsForValue().set(key,value); } public String getValueByKey(String key){ return stringRedisTemplate.opsForValue().get(key); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值