首先我们需要配置一个缓存管理器,然后才能使用缓存注解来管理缓存
package com.cherish.servicebase.handler;import com.fasterxml.jackson.annotation.jsonautodetect;import com.fasterxml.jackson.annotation.propertyaccessor;import com.fasterxml.jackson.databind.objectmapper;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.connection.redisconnectionfactory;import org.springframework.data.redis.core.redistemplate;import org.springframework.data.redis.serializer.jackson2jsonredisserializer;import org.springframework.data.redis.serializer.redisserializationcontext;import org.springframework.data.redis.serializer.redisserializer;import org.springframework.data.redis.serializer.stringredisserializer;import java.time.duration;@configuration@enablecachingpublic class redisconfig extends cachingconfigurersupport { @bean public redistemplate<string, object> redistemplate(redisconnectionfactory factory) { redistemplate<string, object> template = new redistemplate<>(); 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); template.setconnectionfactory(factory); //key序列化方式 template.setkeyserializer(redisserializer); //value序列化 template.setvalueserializer(jackson2jsonredisserializer); //value hashmap序列化 template.sethashvalueserializer(jackson2jsonredisserializer); return template; } @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)) .serializekeyswith(redisserializationcontext.serializationpair.fromserializer(redisserializer)) .serializevalueswith(redisserializationcontext.serializationpair.fromserializer(jackson2jsonredisserializer)) .disablecachingnullvalues(); rediscachemanager cachemanager = rediscachemanager.builder(factory) .cachedefaults(config) // 可以给每个cachename不同的rediscacheconfiguration 设置不同的过期时间 //.withcacheconfiguration("users",config.entryttl(duration.ofseconds(100))) .transactionaware() .build(); return cachemanager; }}
1、@cacheable标记在方法或者类上,标识该方法或类支持缓存。spring调用注解标识方法后会将返回值缓存到redis,以保证下次同条件调用该方法时直接从缓存中获取返回值。这样就不需要再重新执行该方法的业务处理过程,提高效率。
@cacheable常用的三个参数如下:
cachenames 缓存名称
key 缓存的key,需要注意key的写法哈
condition 缓存执行的条件,返回true时候执行
示例
//查询所有用户,缓存到redis中 @getmapping("/selectfromredis") @cacheable(cachenames = "users",key = "'user'") public resultdata getuserredis(){ list<user> list = userservice.list(null); return resultdata.ok().data("user",list); }
第一次查询是从数据库查询的,然后缓存到redis中 使用redis可视化工具查看缓存的信息
第二查询走了缓存控制台没有输出 ,所以走的redis缓存 就是在redis中获取结果直接返回。
@cacheevict标记在方法上,方法执行完毕之后根据条件或key删除对应的缓存。常用的属性:
allentries boolean类型,表示是否需要清除缓存中的所有元素
key 需要删除的缓存的key
//调用这个接口结束后,删除指定的redis缓存 @postmapping("updateuser") @cacheevict(cachenames ="users",key = "'user'") public resultdata updateuser(@requestbody user user){ string id = user.getid(); querywrapper<user> wrapper=new querywrapper<>(); wrapper.eq("id",id); boolean b = userservice.update(user, wrapper); return resultdata.ok().data("flag",b); }
//不删除redis缓存 @postmapping("updateuser2") public resultdata updateuser2(@requestbody user user){ string id = user.getid(); querywrapper<user> wrapper=new querywrapper<>(); wrapper.eq("id",id); boolean b = userservice.update(user, wrapper); return resultdata.ok().data("flag",b); }
当我们更新数据库的数据时候,需要把redis的缓存清空。否则我们查询的数据是redis缓存中的数据,这样就会导致数据库和缓存数据不一致的问题。
示例 调用没有加 @cacheevict 注解的接口修改数据,在查询得到的数据是未修改之前的。
所以在我们调用修改数据的接口的时候需要清除缓存
加上 @cacheevict 注解 清除对应的缓存此时在查询数据发现数据是最新的,跟数据库保持一致。
过期时间我们已经实现了spring cache的基本功能,整合了redis作为rediscachemanger,但众所周知,我们在使用@cacheable注解的时候是无法给缓存这是过期时间的。但有时候在一些场景中我们的确需要给缓存一个过期时间!这是默认的过期时间
数据有效期时间
自定义过期时间
使用新的redis配置,再次查询缓存到数据看数据有效期
以上就是springboot与redis整合中@cacheable怎么使用的详细内容。