缓存方法返回值

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表达式
相关推荐
虾球xz2 小时前
游戏引擎学习第64天
redis·学习·游戏引擎
Hello.Reader9 小时前
Redis大Key问题全解析
数据库·redis·bootstrap
B1nna12 小时前
Redis学习(三)缓存
redis·学习·缓存
程序员JerrySUN15 小时前
Yocto 项目 - 共享状态缓存 (Shared State Cache) 机制
linux·嵌入式硬件·物联网·缓存·系统架构
A227418 小时前
Redis——缓存雪崩
java·redis·缓存
weisian15118 小时前
Redis篇--应用篇3--数据统计(排行榜,计数器)
数据库·redis·缓存
言之。18 小时前
Redis单线程快的原因
数据库·redis·缓存
LYX36931 天前
Docker 安装mysql ,redis,nacos
redis·mysql·docker
中古传奇1 天前
【3.1 以太网RDMA优化--网卡缓存资源维度】
网络·缓存·rdma
计算机毕设定制辅导-无忧学长1 天前
Redis 持久化机制详解
redis