缓存方法返回值

1. 业务需求

前端用户查询数据时,数据查询缓慢耗费时间;

基于缓存中间件实现缓存方法返回值:实现流程用户第一次查询时在数据库查询,并将查询的返回值存储在缓存中间件中,在缓存有效期内前端用户再次查询时,从缓存中间件缓存获取

2. 基于Redis实现

参考1

2.1 简单实现

引入cache依赖

java 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

在redis配置类中添加cache缓存机制

java 复制代码
/**
 * redis配置
 *
 * @author ruoyi
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    /**
     * 方法返回值缓存策略
     *
     * @param factory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(2 * 60))//过期超时时间 2分钟
                .disableCachingNullValues();

        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .transactionAware()
                .build();
    }

	//......其他配置不展示.....
}

启动类开始方法缓存@EnableCaching

java 复制代码
package com.ruoyi;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;

/**
 * 启动程序
 *
 * @author ruoyi
 */
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableCaching
public class RuoYiApplication
{
    public static void main(String[] args)
    {
        // System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(RuoYiApplication.class, args);
        System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
    }
}

业务层设置缓存方法

java 复制代码
    @Override
    @Cacheable(cacheNames = "selectuserlist",key = "#user.userId")
    public List<SysUser> selectUserList(SysUser user)
    {
        return userMapper.selectUserList(user);
    }

测试效果

第一次请求时


第二次请求时,没有查询数据库

查询userId为2的用户

两分钟过后

2.2 设置自定义过期时长

创建RedisCache解析器

java 复制代码
package com.ruoyi.framework.config.properties;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;

import java.time.Duration;

/**
 * RedisCache解析器
 */
public class MyRedisCacheManager extends RedisCacheManager {
    public MyRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
        super(cacheWriter, defaultCacheConfiguration);
    }

    @Override
    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
        //解析name字段
        if (!StringUtils.isEmpty(name) && name.contains("#")) {
            //获取时间
            String numStr = name.split("#")[1];
            if (StringUtils.isNumeric(numStr)) {
                //重置缓存时长
                return super.createRedisCache(name, cacheConfig.entryTtl(Duration.ofSeconds(Integer.parseInt(numStr))));
            }
        }
        return super.createRedisCache(name, cacheConfig);
    }
}

配置RedisConfig

java 复制代码
package com.ruoyi.framework.config;

import com.ruoyi.framework.config.properties.MyRedisCacheManager;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * redis配置
 *
 * @author ruoyi
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    /**
     * 方法返回值缓存策略
     *
     * @param factory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(2 * 60))//过期超时时间 2分钟
                .disableCachingNullValues();

//        return RedisCacheManager.builder(factory)
//                .cacheDefaults(config)
//                .transactionAware()
//                .build();
        return new MyRedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(factory), config);
    }
	//...............其他配置...略..........
}

使用160秒有效

java 复制代码
    @Override
    @Cacheable(cacheNames = "selectuserlist#160",key = "#user.userId")
    public List<SysUser> selectUserList(SysUser user)
    {
        return userMapper.selectUserList(user);
    }

2.3 注解Cacheable.key

  • 声明访问缓存的键,由于缓存本质上是键值存储,因此每次调用缓存方法时都需要使用键去访问。
  • 缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。这个 key 可以使用 spEL 表达式来编写。
  • 这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用"#参数名"或者"#p参数index"。
java 复制代码
@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@Cacheable(cacheNames="books", key="#p0")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
    
@Cacheable(cacheNames="books", key="#p0.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
  • spEL表达式
相关推荐
lssjzmn3 小时前
🚀如何基于Redis的ZSet数据结构设计一个通用的,简单的,可靠的延迟消息队列,以RedisTemplate为例
redis
jakeswang5 小时前
应用缓存不止是Redis!——亿级流量系统架构设计系列
redis·分布式·后端·缓存
.Shu.6 小时前
Redis zset 渐进式rehash 实现原理、触发条件、执行流程以及数据一致性保障机制【分步源码解析】
数据库·redis·缓存
君不见,青丝成雪6 小时前
大数据技术栈 —— Redis与Kafka
数据库·redis·kafka
悟能不能悟6 小时前
排查Redis数据倾斜引发的性能瓶颈
java·数据库·redis
切糕师学AI6 小时前
.net core web程序如何设置redis预热?
redis·.netcore
Mi_Manchikkk7 小时前
Java高级面试实战:Spring Boot微服务与Redis缓存整合案例解析
java·spring boot·redis·缓存·微服务·面试
xiao-xiang8 小时前
redis-集成prometheus监控(k8s)
数据库·redis·kubernetes·k8s·grafana·prometheus
柳贯一(逆流河版)20 小时前
Spring 三级缓存:破解循环依赖的底层密码
java·spring·缓存·bean的循环依赖
TT哇1 天前
@[TOC](计算机是如何⼯作的) JavaEE==网站开发
java·redis·java-ee