SpringBoot Redis缓存数据实现解析
这篇文章主要介绍了SpringBootRedis缓存数据实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
1.启用对缓存的支持
spring对缓存的支持有两种方式:
a.注解驱动的缓存
b.XML声明的缓存
本文主要介绍纯Java配置的缓存,那么必须在配置类上添加@EnableCaching,这样的话就能启动注解驱动的缓存。
2.使用Redis缓存
缓存的条目不过是一个键值对(Key-Value),其中key描述了产生value的操作和参数,因此会很自然的想到Redis。
Redis可以用来为srping缓存抽象机制缓存条目,Spring-Data-Redis提供了RedisCacheManager,这是CacheManager的一个实现。RedisCacheManager会与Redis服务器协作,通过RedisTemplate将缓存条目储存到Redis中。
为了使用RedisCacheManager,我们需要RedisTmeplateBean配置以及RedisConnectionFactory实现类(JedisConnectionFactoryBean配置)。
3.配置将缓存条目存储在Redis服务器的缓存管理器。
前提需要在pom.xml引入
org.springframework.boot spring-boot-starter-data-redis
在application.properties中配置redis连接相关参数
#配置redis #在RedisProperties.class有redis的默认配置,默认host为localhost,默认端口为6379 spring.redis.host=127.0.0.1 spring.redis.port=6379
配置缓存管理器
packagecom.niugang; importjava.lang.reflect.Method; importorg.springframework.cache.CacheManager; importorg.springframework.cache.annotation.EnableCaching; importorg.springframework.cache.interceptor.KeyGenerator; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.data.redis.cache.RedisCacheManager; importorg.springframework.data.redis.connection.jedis.JedisConnectionFactory; importorg.springframework.data.redis.core.RedisTemplate; importorg.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; importorg.springframework.data.redis.serializer.StringRedisSerializer; importcom.fasterxml.jackson.annotation.PropertyAccessor; importcom.fasterxml.jackson.databind.ObjectMapper; importcom.fasterxml.jackson.annotation.JsonAutoDetect; @Configuration //没有@EnableCaching这个注解的话,代码不会报错,就是内容不会放入redis中 @EnableCaching publicclassRedisConfig{ /** *緩存管理器,不管用什么的缓存,都必须有缓存管理器 */ @Bean publicCacheManagercacheManager(){ RedisCacheManagerredisCacheManager=newRedisCacheManager(redisTemplate()); /* *设置缓存保留的时间,默认是永久保存 */ redisCacheManager.setDefaultExpiration(60); returnredisCacheManager; } @Bean publicJedisConnectionFactoryjedisConnectionFactory(){ JedisConnectionFactoryjedisConnectionFactory=newJedisConnectionFactory(); jedisConnectionFactory.afterPropertiesSet(); returnjedisConnectionFactory; } /** *redis默认对象序列化是通过jdk来序列化的,这里面不用默认序列化方式,用JackJson进行序列化 * *设置key的类型为String类型 * *@return */ @Bean @SuppressWarnings({"rawtypes","unchecked"}) publicRedisTemplateredisTemplate(){ RedisTemplate redisTemplate=newRedisTemplate (); redisTemplate.setConnectionFactory(jedisConnectionFactory()); //使用Jackson2JsonRedisSerialize替换默认序列化 Jackson2JsonRedisSerializerjackson2JsonRedisSerializer=newJackson2JsonRedisSerializer(Object.class); ObjectMapperobjectMapper=newObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); //设置value的序列化规则和key的序列化规则 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setKeySerializer(newStringRedisSerializer()); redisTemplate.afterPropertiesSet(); returnredisTemplate; } /** *生产key的策略 *@return */ @Bean publicKeyGeneratorwiselyKeyGenerator(){ returnnewKeyGenerator(){ @Override publicObjectgenerate(Objecttarget,Methodmethod,Object...params){ StringBuildersb=newStringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for(Objectobj:params){ sb.append(obj.toString()); } returnsb.toString(); } }; } }
4.为方法添加注解以支持缓存
spring的缓存抽象在很大程度上是围绕切面构建的,在sprng中启用缓存时,会创建一个切面,它触发
一个或更多的spring的缓存注解。
spring提供了四个注解来声明缓存规则
5.填充缓存
@Cacheable和CachePut都可以填充缓存,他们之间还是确有差异的。
@Cacheable和CachePut共同的属性
6.自定义key
@Cacheable和CachePut都有一个名为key的属性,这个属性能够替代默认的key,t它是通过SpEl(SpringEl表达式)表达式计算得到的。具体到我们的业务场景save(Useruser),我们需要将key设置保存为User对象中的id,我们通过mysql数据库自动生成id,此时参数中的User对象还没有id.幸好有SpEl。
7.在UserService中添加如下方法。
/** *查询全部 * *@Cacheable,先在缓存中找,有则直接返回,不去调用方法,没有则调用方法,将结果放入缓存中 * * *默认的key是基于方法参数来确定的,queryList()这个方法没有参数,所以需要生成key的策略 */ //@Cacheable(value="findAll",keyGenerator="wiselyKeyGenerator") publicListqueryList(){ returnuserDao.findAll(); } /** *@Cachable会条件性的出发对方法的调用,这个取决于缓存中是不是已经有所需要的值。对于 *所注解的方法,@CachePut采用一种更为直接的流程。带有@CachePut注解的方法始终都会调用, *而的返回值也会放入到缓存中。 *@CachePut先将对象保存到db中,返回的对象User中的id作为缓存中的key *result能够得到返回的User *@paramuser */ @CachePut(value="save",key="#result.id.toString()") @Transactional publicUsersave(Useruser){ log.info("添加对象"); returnuserDao.save(user); } /** *函数功能:根据id查询 * *当get被调用时,缓存切面会拦截调用并在缓存中查找之前以名findOne存储的返回值。缓存的key是 *传递到get()方法的id参数,这个参数还必须是String类型。如果按照这个key能 *够找到值得话就返回找到的值,方法不会在被调用。如果没有找到值的话,那就会调用这个方法 *并将返回值放到缓存之中。 * *默认是以参数id的值作为缓存中的key的 * *没有添加key="#id.toString()"可能为报java.lang.Integercannotbecasttojava.lang.String *因为key的类型为String类型 */ @Cacheable(value="findOne",key="#id.toString()") publicUserget(Integerid){ log.info("从数据查询id为:{}的对象",id); returnuserDao.findOne(id); } /** *删除 *@CacheEvict移除条目,可以用在返回值为void的方法上,但是@Cacheable,@CachePut不能用在返回值为void的方法上 * *@paramid */ @CacheEvict(value="save",key="#id.toString()") @Transactional publicvoiddelete(intid){ log.info("从数据删除id为:{}的对象",id); userDao.delete(id); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。