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;
    }
}
相关推荐
qmx_0731 分钟前
HTB-Jerry(tomcat war文件、msfvenom)
java·web安全·网络安全·tomcat
小安运维日记32 分钟前
Linux云计算 |【第四阶段】NOSQL-DAY1
linux·运维·redis·sql·云计算·nosql
为风而战39 分钟前
IIS+Ngnix+Tomcat 部署网站 用IIS实现反向代理
java·tomcat
kejijianwen2 小时前
JdbcTemplate常用方法一览AG网页参数绑定与数据寻址实操
服务器·数据库·oracle
编程零零七2 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
技术无疆3 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
2401_858286113 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
铁松溜达py3 小时前
编译器/工具链环境:GCC vs LLVM/Clang,MSVCRT vs UCRT
开发语言·网络
everyStudy3 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript
C-SDN花园GGbond4 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法