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;
    }
}
相关推荐
乌啼霜满天2491 分钟前
Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
java·spring boot·spring·mvc
tangliang_cn6 分钟前
java入门 自定义springboot starter
java·开发语言·spring boot
程序猿阿伟7 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
Grey_fantasy17 分钟前
高级编程之结构化代码
java·spring boot·spring cloud
新知图书18 分钟前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
威威猫的栗子20 分钟前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python
力透键背20 分钟前
display: none和visibility: hidden的区别
开发语言·前端·javascript
bluefox197921 分钟前
使用 Oracle.DataAccess.Client 驱动 和 OleDB 调用Oracle 函数的区别
开发语言·c#
弗锐土豆24 分钟前
工业生产安全-安全帽第二篇-用java语言看看opencv实现的目标检测使用过程
java·opencv·安全·检测·面部
Elaine20239124 分钟前
零碎04 MybatisPlus自定义模版生成代码
java·spring·mybatis