Redis使用场景---热点数据缓存

1.1 什么是缓存?

缓存(Cache)是计算机科学中的一种技术,旨在提高数据访问速度。它是一种临时存储机制,用于存储常用或近期访问的数据,以便快速访问,减少延迟

1.2 缓存的原理

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

适合缓存的数据通常是那些需要快速访问、访问频率高、计算成本高且变化不频繁的数据。

1.4 哪个组件可以作为缓存

  1. redis组件

  2. memory组件

  3. ehcache组件 等......

1.5 java使用redis如何实现缓存功能

1.5.1 SpringBoot整合redis配置依赖

使用Maven,可以在pom.xml中添加以下依赖: 这里使用的是JDK8

java 复制代码
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--mysql的驱动依赖 3.-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.7</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

1.5.2 修改 application.properties 配置文件 这是示例

java 复制代码
spring.application.name=springboot-redis-cache

#??????
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring-boot?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=kkkk

#??mybatis???????
mybatis-plus.mapper-locations=classpath*:mapper/*.xml

#????-sql??
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#redis??
spring.redis.host=192.168.202.199
spring.redis.port=6379
spring.redis.database=1

业务层代码

java 复制代码
@Service
public class ClazzServiceImpl implements ClazzService {

    @Autowired
    private ClazzDao clazzDao;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Override
    public Clazz getById(Integer id) {
        //1.查询redis缓存是否命中
        ValueOperations<String, Object> forValue = redisTemplate.opsForValue();
        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;
    }

    @Override
    public Clazz save(Clazz clazz) {
        int insert = clazzDao.insert(clazz);
        return clazz;
    }

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

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

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

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

spring框架。---aop切面来解决。

1.6 使用缓存注解完成缓存

必须spring缓存使用的组件。 序列化

java 复制代码
 @Bean
    public 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;
    }

开始注解缓存

@EnableCaching 注解在Spring应用中用于启用缓存,当你使用Redis作为缓存提供者时,它的作用是相同的:启用缓存机制并允许你在应用中使用缓存注解,如 @Cacheable、@CachePut 和 @CacheEvict。

使用:

java 复制代码
package com.ykq.service.impl;

import com.ykq.dao.ClazzDao;
import com.ykq.entity.Clazz;
import com.ykq.service.ClazzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

/**
 * @Author: 
 * @Description:
 * @Date: Create in 14:36 2024/7/24
 */
@Service
public class ClazzServiceImpl implements ClazzService {

    @Autowired
    private ClazzDao clazzDao;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    //Cacheable:表示查询时使用的注解。 cacheNames:缓存的名称  key:缓存的唯一表示值
    //   1. 查询缓存中是否存在名称为cacheNames::key的值
         //2.如果存在则方法不会执行
    //   3. 如果不存在则执行方法体并把方法的返回结果放入缓存中cacheNames::key
    @Cacheable(cacheNames ={ "clazz"}, key = "#id")
    @Override
    public Clazz getById(Integer id) {
        //查询数据库
        Clazz clazz = clazzDao.selectById(id);
        return clazz;
    }

    @Override
    public Clazz save(Clazz clazz) {
        int insert = clazzDao.insert(clazz);
        return clazz;
    }

    //CachePut:表示修改时使用的注解.
    // 1. 先执行方法体
    // 2. 把方法的返回结果放入缓存中
    @CachePut(cacheNames = "clazz", key = "#clazz.cid")
    public Clazz update(Clazz clazz) {
        //修改数据库
        int i = clazzDao.updateById(clazz);
        return clazz;
    }

    //CacheEvict:表示删除时使用的注解
    // 1. 先执行方法体
    // 2. 把缓存中名称为cacheNames::key的值删除
    @CacheEvict(cacheNames = "clazz", key = "#cid")
    @Override
    public int delete(Integer cid) {
        int i = clazzDao.deleteById(cid);
        return i;
    }
}
相关推荐
花间相见3 分钟前
【计算基础|Redis01】【上手】安装连接、配置与通用命令
数据库·后端·面试
2601_970703834 分钟前
中国除湿机与湿度控制行业研究报告
java·大数据·人工智能
geovindu10 分钟前
Pivoting and Unpivoting Data in SQL using postgreSQL 18
大数据·数据库·数据仓库·sql·postgresql·数据库开发·数据库架构
我命由我1234513 分钟前
6-3.Python 异常处理 - 异常处理进阶(else 块与 finally 块、异常传递、自定义异常)
开发语言·前端·数据库·后端·python·学习·java-ee
额额额对了17 分钟前
【项目实战】从IMX6ULL环境监测到N647 AI视觉加速
linux·开发语言·嵌入式硬件
深入云栈19 分钟前
Netty 4.2.x 源码深度解析 (二十一):Pipeline 事件传播 —— Inbound 与 Outbound 的双向流转
java·后端·架构
Elastic 中国社区官方博客21 分钟前
Elastic 重大事件功能如何将 100 条日志样本转化为检测规则
大数据·运维·数据库·人工智能·elasticsearch·搜索引擎
adinnet202621 分钟前
持续智能问数:多轮对话状态管理、下钻钻取与经营驾驶舱的演进
javascript·数据库·人工智能
熊猫钓鱼>_>30 分钟前
端侧 NPU 轻量大模型推理接入笔记【鸿蒙心迹】
开发语言·笔记·华为·ai编程·harmonyos·鸿蒙
外收内放33 分钟前
FastAPI猜字谜实战(8):收官
开发语言·python·学习·fastapi