为了提高查询的性能,我们通常采用Redis缓存解决。
Redis环境搭建
docker run ‐di ‐‐name=tensquare_redis ‐p 6379:6379 redis
SpringDataRedis
Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问
redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate
提供了redis各种操作。
实现文章的缓存处理
查询文章操作缓存
(1)在tensquare_article 的pom.xml引入依赖
<dependency>
<groupId>org.springframework.bootgroupId> <artifactId>spring‐boot‐starter‐data‐redisartifactId> dependency>
(2)修改application.yml ,在spring节点下添加配置
redis:
host: 192.168.184.134
(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; }
修改或删除后清除缓存
/**
* 修改
* @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); }
缓存过期处理
修改findById方法 ,设置1天的过期时间
redisTemplate.opsForValue().set("article_" + id, article,1,TimeUnit.DAYS);
为了方便测试,我们可以把过期时间改为10秒
redisTemplate.opsForValue().set("article_" + id, article,10,TimeUnit.SECONDS);
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集合
Spring Cache
spring cache跟Redis没有关系,是springboot本身提供的一个缓存,无需导入Redis的包和配置文件。比Redis简单,但功能没有Redis强大,比如上面的方法一个都没有。也无法设置过期时间,所以一般用在findbyid
@Cacheable-------使用这个注解的方法在执行后会缓存其返回结果。
@CacheEvict--------使用这个注解的方法在其执行前或执行后移除Spring Cache中的某些
元素
改造上面的findbyid(使用spring cache):
(1)在GatheringService的findById方法添加缓存注解,这样当此方法第一次运行,在缓存中没有找到对应的value和key,则将查询结果放入缓存
/**
* 根据ID查询实体
* @param id
* @return
*/
/*value值随便写,代表的是缓存的名称,key就是存进去的ID,直接用#号就能拿到方法中的参数值*/
@Cacheable(value="gathering",key="#id") public Gathering findById(String id) { return gatheringDao.findById(id).get(); }
value值随便写,代表的是缓存的名称,key就是存进去的ID,直接用#号就能拿到方法中的参数值。这样写就是以后要执行findbyid就会先去名为gathering的缓存中通过ID找
(2)当我们对数据进行删改的时候,需要更新缓存。其实更新缓存也就是清除缓存,因为清除缓存后,用户再次调用查询方法无法提取缓存会重新查找数据库中的记录并放入缓存。
在GatheringService的update、deleteById方法上添加清除缓存的注解
/**
* 修改
* @param gathering
*/
@CacheEvict(value="gathering",key="#gathering.id") //这个地方要注意,key必须是ID public void update(Gathering gathering) { gatheringDao.save(gathering); } /** * 删除 * @param id */ @CacheEvict(value="gathering",key="#id") public void deleteById(String id) { gatheringDao.deleteById(id); }
面试问题总结
在项目中哪部分业务用到缓存
- findbyid都要用
你说一下项目中是如何使用缓存的
1.Redis
2.springcache
需要过期时间用Redis。不要就用springcache
说一下如何设置缓存过期时间
修改findById方法 ,设置1天的过期时间:
redisTemplate.opsForValue().set("article_" + id, article,1,TimeUnit.DAYS);
我们可以把过期时间改为10秒:
redisTemplate.opsForValue().set("article_" + id, article,10,TimeUnit.SECONDS);