【探花交友】SpringCache

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 【探花交友】SpringCache

通用缓存SpringCache

1.实现缓存逻辑有2种方式:

2.每个接口单独控制缓存逻辑


统一控制缓存逻辑Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化我们开发;


Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;


Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache ,ConcurrentMapCache等;


每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。


使用Spring缓存抽象时我们需要关注以下两点;


1、确定方法需要被缓存以及他们的缓存策略


2、从缓存中读取之前缓存存储的数据


内部使用AOP的形式,对redis操作进行简化


重要概念

名称 解释
@Cacheable 主要针对方法配置,能够根据方法的请求参数对其进行缓存
@CacheEvict 清空缓存

入门案例

导入依赖

导入SpringDataRedis的依赖,并在application.yml中配置 (略)

开启缓存支持

然后在启动类注解@EnableCaching开启缓存

@SpringBootApplication
@EnableCaching  //开启缓存
public class DemoApplication{
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

编写UserInfoService

package com.tanhua.server.test;
import com.tanhua.domain.db.UserInfo;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class UserInfoService {
    //根据id查询
    public UserInfo queryById(Long userId) {
        //从数据库查询
        UserInfo user = new UserInfo();
        user.setId(userId);
        user.setNickname("ceshi");
        return user;
    }
    //根据id修改
    public void update(Long userId) {
        UserInfo user = new UserInfo();
        user.setId(userId);
        user.setNickname("itcast");
    }
}

缓存@Cacheable

@Cacheable注解会先查询是否已经有缓存,有会使用缓存,没有则会执行方法并缓存

@Cacheable(value = "user",key = "#userId")
public UserInfo queryById(Long userId) {
    //从数据库查询
    UserInfo user = new UserInfo();
    user.setId(userId);
    user.setNickname("ceshi");
    return user;
}

此处的value是必需的,它指定了你的缓存存放在哪块命名空间。


此处的key是使用的spEL表达式,参考上章。这里有一个小坑,如果你把methodName换成method运行会报错,观察它们的返回类型,原因在于methodName是String而methoh是Method。


此处的User实体类一定要实现序列化public class User implements Serializable,否则会报java.io.NotSerializableException异常。


到这里,你已经可以运行程序检验缓存功能是否实现。

清除@CacheEvict

@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空 。


//根据id修改
@CacheEvict(value = "user",key = "#userId")
public void update(Long userId) {
    //修改用户
    UserInfo user = new UserInfo();
    user.setId(userId);
    user.setNickname("itcast");
}

视频列表缓存处理

修改VideoService,分页列表存入缓存,发布视频删除缓存

由于使用Reids缓存处理数据时,不能缓存ResponseEntity对象,所以需要修改方法返回值为

PageResult

@Cacheable(value="videoList",key="#page + '_' +  #pagesize")
public PageResult queryVideoList(Integer page, Integer pagesize) {
    //1、调用API查询 : PageReulst<Video>
    PageResult result = videoApi.findAll(page,pagesize);
    //2、获取分页中的list集合  List<Video>
    List<Video> items = (List<Video>)result.getItems();
    //3、循环视频列表,一个Video构造一个Vo
    List<VideoVo> list = new ArrayList<>();
    for (Video item : items) {
        UserInfo userInfo = userInfoApi.findById(item.getUserId());
        VideoVo vo = VideoVo.init(userInfo, item);
        //从redis中获取,当前用户是否已经关注了视频发布作者
        String key = "followUser_"+UserHolder.getUserId()+"_"+item.getUserId();
        if (redisTemplate.hasKey(key)) {
            vo.setHasFocus(1);
        }
        list.add(vo);
    }
    //4、替换result中的item数据
    result.setItems(list);
    //5、构造返回值
    result;
}

发布视频清空缓存

修改VideoService,分页列表存入缓存,发布视频删除缓存

由于使用Reids缓存处理数据时,不能缓存ResponseEntity对象,所以需要修改方法返回值为

PageResult

//发布视频
@CacheEvict(value="videoList",allEntries = true)
public ResponseEntity saveVideo(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
    //1、图片上传到阿里云oss,获取请求地址
    String picUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
    //2、视频上传到fdfs上,获取请求地址
    String filename = videoFile.getOriginalFilename(); //xxxx.avi
    //获取文件后缀
    String sufix = filename.substring(filename.lastIndexOf(".")+1);
    StorePath storePath = client.uploadFile(videoFile.getInputStream(),
                                            videoFile.getSize(), sufix, null); //文件输入流,文件长度(大小),文件的后缀名,元数据(null)
    String videoUrl = webServer.getWebServerUrl() + storePath.getFullPath();
    //3、构建Video对象,并设置属性
    Video video = new Video();
    video.setPicUrl(picUrl);
    video.setVideoUrl(videoUrl);
    video.setText("传智播客是一个负责任的教育机构~"); //客户端未传递,手动模拟
    video.setUserId(UserHolder.getUserId());
    //4、调用api保存
    videoApi.save(video);
    //5、构建返回值
    return ResponseEntity.ok(null);
}
相关实践学习
基于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
相关文章
|
监控 负载均衡 Dubbo
【探花交友】day00—探花交友前置Dubbo(一)
【探花交友】day00—探花交友前置Dubbo
111 0
|
4月前
|
缓存 NoSQL Redis
黑马点评笔记 redis缓存三大问题解决(二)
黑马点评笔记 redis缓存三大问题解决
117 0
|
4月前
|
缓存 NoSQL 安全
黑马点评笔记 redis缓存三大问题解决(一)
黑马点评笔记 redis缓存三大问题解决
177 0
|
SpringCloudAlibaba 负载均衡 Dubbo
【探花交友】day00—探花交友前置Dubbo(二)
【探花交友】day00—探花交友前置Dubbo(二)
125 0
|
Dubbo NoSQL 测试技术
【探花交友】day07—搜附近(一)
【探花交友】day07—搜附近
117 0
|
Dubbo 应用服务中间件 测试技术
【探花交友】day07—搜附近(三)
【探花交友】day07—搜附近(三)
186 0
|
存储 NoSQL Dubbo
【探花交友】day07—搜附近(二)
【探花交友】day07—搜附近(二)
135 0
|
存储 NoSQL API
【探花交友】day04—圈子功能实现(二)
【探花交友】day04—圈子功能实现(二)
134 0
|
存储 SQL 缓存
【探花交友】day04—圈子功能实现(一)
【探花交友】day04—圈子功能实现
108 0
|
API
【探花交友】day04—圈子功能实现(三)
【探花交友】day04—圈子功能实现(三)
75 0