当前位置: 首页 > news >正文

Redis的使用场景——热点数据缓存

热点数据缓存

Redis的使用场景——热点数据的缓存

1.1 什么是缓存

为了把一些经常访问的数据,放入缓存中以减少对数据库的访问效率,从而减少数据库的压力,提高程序的性能。【在内存中存储】

1.2 缓存的原理

  1. 查询缓存中是否存在对应的数据
  2. 如果缓存中有,即命中,直接返回给程序
  3. 如果没有明中,访问查询数据库
  4. 把查询的数据返回给程序,并同时将查询的数据放入缓存

在这里插入图片描述

1.3 什么样的数据适合放入缓存中

  1. 查询频率高且修改频率低的
  2. 数据安全性低的

1.4 哪个组件可以作为缓存

  1. redis组件
  2. memory组件
  3. ehcache组件等

1.5 java使用redis如何实现缓存

准备

  1. 首先创建一个springboot项目

    在这里插入图片描述

  2. 配置文件

    server.port=端口号
    #数据源
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/数据库名称?serverTimezone=Asia/Shanghai
    spring.datasource.username=用户名
    spring.datasource.password=密码#mybatis配置文件
    mybatis.mapper-locations=classpath:mapper/*.xml#日志
    mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl#redis
    spring.redis.host=IP地址
    spring.redis.port=6379
    spring.redis.database=4
    
  3. 修改mysql依赖,添加mybatis-plus的依赖

    <!--mysql依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatisplus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.4</version></dependency>
    
  4. 创建实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @TableName("class")
    public class Clazz {//设置为主键且自增@TableId(type = IdType.AUTO)private Integer cid;private String cname;private String teacher;
    }
    
  5. 创建dao层接口

    @Repository
    public interface ClazzDao extends BaseMapper<Clazz> {
    }
    
  6. 创建service层和业务实现类

    • 接口

      public interface ClazzService {//添加public Clazz insert(Clazz clazz);//删除public int del(Integer id);//修改public Clazz updateById(Clazz clazz);//查询public Clazz getById(Integer id);
      }
      
    • 业务实现类

      @Service
      public class ClazzServiceImpl implements ClazzService {@Autowiredprivate ClazzDao clazzDao;//查询@Overridepublic Clazz getById(Integer id) {//查询数据库Clazz clazz = clazzDao.selectById(id);return clazz;}//增加@Overridepublic Clazz insert(Clazz clazz) {clazzDao.insert(clazz);return clazz;}//删除@Overridepublic int del(Integer id) {int i = clazzDao.deleteById(id);return i;}@Overridepublic Clazz updateById(Clazz clazz) {//修改数据库int i = clazzDao.updateById(clazz);return clazz;}
      
  7. controller控制层

    @RestController
    @RequestMapping("/clazz")
    public class ClazzController {@Autowiredprivate ClazzService clazzService;//添加@PostMapping("/insert")public Clazz insert(@RequestBody Clazz clazz){return clazzService.insert(clazz);}//根据id查询@GetMapping("/getById/{id}")public Clazz getById(@PathVariable Integer id){Clazz clazz = clazzService.getById(id);return clazz;}//删除@DeleteMapping("/del/{id}")public Integer del(@PathVariable Integer id){int del = clazzService.del(id);return del;}//编辑@PutMapping("/update")public Clazz update(@RequestBody Clazz clazz){return clazzService.updateById(clazz);}
    }
    
  8. 在main主函数中添加注入dao

    @SpringBootApplication
    @MapperScan("com.zmq.dao")
    public class SpringbootRedis02Application {public static void main(String[] args) {SpringApplication.run(SpringbootRedis02Application.class, args);}
    }
    

缓存处理在service层处理优化。【优化查、改、删方法】

  1. 在service业务处理类中注入Redis对象

    //在service层添加redis缓存@Autowiredprivate RedisTemplate<String,Object> redisTemplate;
    
  2. 因为使用redisTemplate,需要序列化,所以,配置序列化配置工具类

    @Configuration
    public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();template.setConnectionFactory(redisConnectionFactory);template.setKeySerializer(jackson2JsonRedisSerializer);template.setValueSerializer(jackson2JsonRedisSerializer);template.setHashKeySerializer(jackson2JsonRedisSerializer);template.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}
    }
    

1.5.1 查询

  1. 获取redis操作字符串的对象
  2. 首先在Redis缓存中查询,如果有直接返回,不需要在访问数据库查询——get方法
  3. 如果Redis缓存中没有,再查询数据库,若在数据库中查询到,就将该数据添加到缓存中——set方法
//查询@Overridepublic Clazz getById(Integer id) {//获取redis操作字符串的对象ValueOperations<String, Object> forValue = redisTemplate.opsForValue();//1.查询redis缓存是否命中Object o = forValue.get("clazz::" + id);//表示缓存命中if(o!=null){return (Clazz) o;}//查询数据库Clazz clazz = clazzDao.selectById(id);//如果数据库存在,将该值添加到缓存中if(clazz!=null){forValue.set("clazz::" + id,clazz);}return clazz;}

1.5.2 修改

若修改操作成功,返回值大于0,就将其数据同步到缓存中——set方法

 @Overridepublic Clazz updateById(Clazz clazz) {//修改数据库int i = clazzDao.updateById(clazz);if(i>0){//修改缓存redisTemplate.opsForValue().set("clazz::"+clazz.getCid(),clazz);}return clazz;}

1.5.3 删除

若数据库删除操作成功,返回值大于0,就根据id删除缓存中该数据——delete方法

 @Overridepublic int delete(Integer cid) {int i = clazzDao.deleteById(cid);if(i>0){//删除缓存redisTemplate.delete("clazz::"+cid);}return i;}

1.6 使用缓存注解完成缓存功能

发现:业务层代码除了要维护核心业务功能外,额外还要维护缓存的代码

如何解决:使用AOP面向切面编程——注解

步骤:

  1. 添加配置spring使用的缓存组件
  2. 开启注解驱动——@EnableCaching

配置文件

@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);//解决查询缓存转换异常的问题ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);// 配置序列化(解决乱码的问题),过期时间600秒RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600)) //缓存过期10分钟 ---- 业务需求。.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//设置key的序列化方式.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) //设置value的序列化.disableCachingNullValues();RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}

开启注解驱动

@SpringBootApplication
@MapperScan("com.zmq.dao")
@EnableCaching
public class SpringbootRedis02Application {public static void main(String[] args) {SpringApplication.run(SpringbootRedis02Application.class, args);}
}

1.6.1 查询——@Cacheable

//查询@Cacheable(cacheNames ={ "clazz"}, key = "#id")@Overridepublic Clazz getById(Integer id) {//查询数据库Clazz clazz = clazzDao.selectById(id);return clazz;}

Cacheable:表示查询时使用的注解

cacheNames:缓存的名称

key:缓存的唯一标识

在方法体之前执行

  1. 查询缓存中是否存在名称为cacheNames::key的值
  2. 如果存在则方法不会执行
  3. 如果不存在,则执行方法体并把方法的返回结果放入缓存中cacheNames::key

1.6.2 修改——@CachePut

 @CachePut(cacheNames = "clazz", key = "#clazz.cid")@Overridepublic Clazz updateById(Clazz clazz) {//修改数据库int i = clazzDao.updateById(clazz);return clazz;}

CachePut:表示修改时使用的注解

  1. 先执行方法体
  2. 把方法的返回结果放入缓存中

1.6.3 删除——@CacheEvict

  @CacheEvict(cacheNames = "clazz", key = "#id")@Overridepublic int delete(Integer cid) {int i = clazzDao.deleteById(cid);return i;}

CacheEvict:表示删除时使用的注解 Evict:驱逐

  1. 先执行方法体
  2. 把缓存中名称为cacheNames::key的值删除

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 昇思25天学习打卡营第19天|DCGAN生成漫画头像
  • 【VSCode实战】Golang无法跳转问题竟是如此简单
  • 浏览器内核的理解
  • 业务记录:处理动态表头的CSV/EXCEL文件
  • 电子档案系统与双层PDF及基于Elasticsearch全文检索技术的探索
  • 大语言模型-GPT2-Generative Pre-Training2
  • java实现OCR图片识别,RapidOcr开源免费
  • 前端工程化-vue项目创建
  • Kafka知识总结(事务+数据存储+请求模型+常见场景)
  • 《Java初阶数据结构》----6.<优先级队列之PriorityQueue底层:堆>
  • USB3.0的等长要求到底是多少?
  • Unity 物理动画:利用物理引擎创造逼真动作
  • Python面试整理-常用标准库
  • PHP反序列化漏洞
  • 将手机作为服务器运行docker服务
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 2017年终总结、随想
  • ComponentOne 2017 V2版本正式发布
  • cookie和session
  • css系列之关于字体的事
  • Git的一些常用操作
  • Java-详解HashMap
  • MySQL用户中的%到底包不包括localhost?
  • PaddlePaddle-GitHub的正确打开姿势
  • uva 10370 Above Average
  • Webpack入门之遇到的那些坑,系列示例Demo
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 工程优化暨babel升级小记
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 三栏布局总结
  • 用Python写一份独特的元宵节祝福
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • HanLP分词命名实体提取详解
  • Mac 上flink的安装与启动
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • ###C语言程序设计-----C语言学习(3)#
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (152)时序收敛--->(02)时序收敛二
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (Python) SOAP Web Service (HTTP POST)
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (多级缓存)缓存同步
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)负载均衡,回话保持,cookie
  • (转)详解PHP处理密码的几种方式
  • (转载)深入super,看Python如何解决钻石继承难题
  • .Net Remoting常用部署结构
  • .net 无限分类
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NET程序员迈向卓越的必由之路