hello,各位小伙伴,最近项目中需要将一些常用的数据缓存起来,毫无疑问,我们采用了redis来缓存数据。那么使用redis缓存数据有哪些方式呢?接下来我会一一道来。
1.环境搭建
引入redis依赖以及spring相关的依赖
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-data-redis</artifactid> </dependency>
2.使用redistemplate
使用redistemplate调用api时,我们通常需要去配置key,value的序列化器,以及创建一个redisutils类来完成缓存的增删改查以及过期时间的设置。
配置如下:
@configuration public class redisconfig { @bean public redistemplate<string, object> redistemplate(redisconnectionfactory factory) { redistemplate<string, object> template = new redistemplate<>(); template.setconnectionfactory(factory); // 设置key的序列化方式 template.setkeyserializer(redisserializer.string()); // 设置value的序列化方式 template.setvalueserializer(redisserializer.json()); // 设置hash的key的序列化方式 template.sethashkeyserializer(redisserializer.string()); // 设置hash的value的序列化方式 template.sethashvalueserializer(redisserializer.json()); template.afterpropertiesset(); return template; } }
redisutils:
public class redisutils { @resource private redistemplate<string, object> redistemplate; public object get(string key) { return key == null ? null : redistemplate.opsforvalue().get(key); } /** * 普通缓存放入 * * @param key 键 * @param value 值 */ public void set(string key, object value) { redistemplate.opsforvalue().set(key, value); } /** * 普通缓存放入并设置时间 * * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 */ public void set(string key, object value, long time) { if (time > 0) { redistemplate.opsforvalue().set(key, value, time, timeunit.seconds); } else { set(key, value); } } /** * 向一张hash表中放入数据,如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 */ public void hset(string key, string item, object value) { redistemplate.opsforhash().put(key, item, value); } /** * 向一张hash表中放入数据,如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 */ public void hset(string key, string item, object value, long time, timeunit timeunit) { redistemplate.opsforhash().put(key, item, value); if (time > 0) { expire(key, time, timeunit); } } /** * @param key 键 * @param map 多个field-value */ public void hmset(string key, map<string, object> map) { redistemplate.opsforhash().putall(key, map); } /** * @param key 键 * @param map 多个field-value * @param time 过期时间 * @param timeunit 时间单位 */ public void hmset(string key, map<string, object> map, long time, timeunit timeunit) { redistemplate.opsforhash().putall(key, map); if (time > 0) { expire(key, time, timeunit); } } /** * @param key 键 * @param item field * @return 获得的值 */ public object hget(string key, string item) { return redistemplate.opsforhash().get(key, item); } /** * @param key 键 * @return hash表中key对应的map */ public map<object, object> hentries(string key) { return redistemplate.opsforhash().entries(key); } /** * @param key 键 * @param value 值 */ public void sadd(string key, object value) { redistemplate.opsforset().add(key, value); } /** * @param key 键 * @param value 值 * @param time 过期时间 * @param timeunit 时间单位 */ public void sadd(string key, object value, long time, timeunit timeunit) { redistemplate.opsforset().add(key, value); if (time > 0) { expire(key, time, timeunit); } } /** * @param key 键 * @return 数据 */ public set<object> smembers(string key) { return redistemplate.opsforset().members(key); } public void expire(string key, long time, timeunit timeunit) { if (time > 0) { redistemplate.expire(key, time, timeunit); } } /** * 根据key 获取过期时间 * * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public long getexpire(string key) { return redistemplate.getexpire(key, timeunit.seconds); } }
通过以上的配置,我们在使用缓存的时候,直接调用api就可以进行操作了。但是有个问题就是,我们在缓存一些常用数据的时候,通常我们需要先判断一下缓存中有没有该key,如果没有我们再去数据库中查询出来,并缓存。
这样的话我们需要去做一些判断的操作,缓存中有就去缓存中取,没有就从数据库中取出来并缓存。那么有没有更方便的操作方式呢,答案当然是有的。
3.使用@enablecaching+@cacheable
spring为我们提供了caching模块,我们可以该模块给我们提供的功能,使用注解很方便完成数据缓存
在使用的过程中,我发现,虽然我们配置了redistemplate
的序列化,但是对于基于注解的redis缓存来说是无效的,我们需要配置自定义的rediscachemanager
配置如下:
@configuration public class redisconfig { @bean public redistemplate<string, object> redistemplate(redisconnectionfactory factory) { redistemplate<string, object> template = new redistemplate<>(); template.setconnectionfactory(factory); // 设置key的序列化方式 template.setkeyserializer(redisserializer.string()); // 设置value的序列化方式 template.setvalueserializer(redisserializer.json()); // 设置hash的key的序列化方式 template.sethashkeyserializer(redisserializer.string()); // 设置hash的value的序列化方式 template.sethashvalueserializer(redisserializer.json()); template.afterpropertiesset(); return template; } @bean public rediscachemanager rediscachemanager(redisconnectionfactory factory) { rediscachewriter rediscachewriter = rediscachewriter.nonlockingrediscachewriter(factory); rediscacheconfiguration rediscacheconfiguration = rediscacheconfiguration.defaultcacheconfig() .serializekeyswith(redisserializationcontext.serializationpair.fromserializer(redisserializer.string())) .serializevalueswith(redisserializationcontext.serializationpair.fromserializer(redisserializer.json())); return new rediscachemanager(rediscachewriter, rediscacheconfiguration); } }
使用方法:
- 在启动类上加上
@enablecaching
- 在需要缓存数据的方法上加上
@cacheable(cachenames = "xxx")
,方法的返回值就是我们需要缓存的数据 - 基于以上的操作,我们就可以很方便的将需要缓存的数据缓存到redis
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论