Springboot - redis缓存注解

问题:
当数据库中存在大量数据,更新频率低,且查询速度较慢时,应该如何提高查询速度?

第一个想法是将无查询条件查出的所有数据,存放在redis中。每次查询时,根据查询条件对redis中取出的数据进行筛选过滤分页,再将结果返回。
但实际操作的时候发现,数据量过大,无论是保存对象集合或者是字符串,都会报内存溢出的错误 Out of Memory allocation。

一、Spring Cache

当调用一个方法时,会把该方法参数和返回结果作为一个键值对存放在缓存中。等下次使用同样的参数调用该方法时,不再执行该方法,而是直接从缓存中获取结果进行返回。需要保证对于一个相同的方法,相同的参数要有相同的返回结果。

提供注解:
@Cacheable:使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回结果
@CacheEvict:会在方法执行前或者执行后移除Spring Cache中的某些元素
@Cacheable
@Cacheable(value=”findList”);
public List<String> findList(QueryParam param) {
	return xxxxMapper.findList(param);
}

当调用这个方法时,会从名为findList的缓存中查询。如果没有,则执行方法,并将结果存入缓存中;否则返回缓存中的结果。上述例子中的,缓存的key为param中的参数以及值,value为List对象。

@Cacheable可配置参数:
value:缓存名称,必须指定至少一个。
key:缓存的key,可以为空(为空时根据redisConfig中的keyGenerator自定义生成)。指定要按照SpEL表达式进行编写。
condition:缓存条件,可以为空。指定要按照SpEL表达式进行编写。返回true/false,仅返回true时进行缓存。

eg:@Cacheable(value = "findList", key = "#param.name", condition = "#param.name != null" )
KeyGenerator

spring默认的生成策略DefaultKeyGenerator:

  • 参数为空:返回0
  • 有一个参数且为null:返回53
  • 参数不是数组:返回参数
  • 其他情况:返回hashCode

当参数列表的值相同时,返回的值是一样的,会导致获取到错误的缓存数据。

自定义cache key的生成方式:
类名 + 方法名 + 参数列表 + 参数值 ——> 哈希散列

@EnableCaching
@Slf4j
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * 自定义key生成规则
     * @return
     */
    @Override
    public KeyGenerator keyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append("&");
                sb.append(method.getName());
                sb.append("&");
                for (Object obj : params) {
                    if (obj != null){
                        sb.append(JSON.toJSONString(obj));
                    }
                }

                log.info("redis cache key str: " + sb.toString());
                log.info("redis cache key sha256Hex: " + DigestUtils.sha1DigestAsHex(sb.toString()));
                return DigestUtils.sha1DigestAsHex(sb.toString());
            }
        };
    }
}

参数示例:

public class QueryParam {

    @ApiModelProperty("名称")
    private String name;

    @ApiModelProperty("页码")
    private Integer pageNum;
    
 	@ApiModelProperty("页面大小")
    private Integer pageSize;
}

key示例:

包名.类名&findList&{"name":"","pageNum":1,"pageSize":10}

二、使用步骤

1.在redisConfig中配置@EnableCaching注解,继承CachingConfigurerSupport类,并实现自定义key生成方法。如上文。

2.在对应的方法上标注@Cacheable(value = “方法名”)

参考文章:
Spring缓存注解@Cache使用
spring boot cache redis 简单理解自定义 KeyGenerator

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值