SpringBoot使用Redis做数据缓存的问题

在SpringBoot中,可以通过Redis做数据的缓存,用户在查询数据时可以直接从缓存中取,减少数据库的压力。

1、首先在SpringBoot中加入Redis的依赖

 <!--集成redis,client改用jedis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>redis.clients</groupId>
                    <artifactId>jedis</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

2、在Redis配置文件中设置缓存配置

package com.zyd.blog.framework.config;

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.cache.interceptor.KeyGenerator;
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.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;

import java.lang.reflect.Method;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;


/**
 * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
 * @version 1.0
 * @website https://www.zhyd.me
 * @date 2018/4/16 16:26
 * @since 1.0
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
//        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//        config = config.entryTtl(Duration.ofMinutes(60*60*24*4));
//
//        // 设置一个初始化的缓存空间set集合
//        Set <String> cacheNames =  new HashSet <>();
//        cacheNames.add("test");
//
//        // 对每个缓存空间应用不同的配置
//        Map <String, RedisCacheConfiguration> configMap = new HashMap <>();
//        configMap.put("test",  config.entryTtl(Duration.ofSeconds(60*60*24*4)));
        return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory))
                // 默认缓存过期时间:天
                .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(30)))
                .transactionAware()
                .build();
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

3、通过数据的查询将数据存入Redis缓存中

@Slf4j
@RestController
@RequestMapping("/api")
public class RestApiController {

    @Autowired
    private BbsForumPostService bbsForumPostService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


/*********************************************别克论坛接口***************************************/

    /**
     * 
     * @param vo
     * @return
     */
    @PostMapping("/listPost")
    @Login
    @BussinessLog(value = "论坛帖子列表", platform = PlatformEnum.WEB)
    public ResponseVO listPost(BbsForumPostConditionVo vo,@LoginUserId Integer userId) throws UnsupportedEncodingException {
    	//通过判断Redis缓存中有没有存在数据,若存在则取缓存数据,不存在则从数据库中查询数据加入到缓存中
        String string = redisTemplate.opsForValue().get("post");
        if ( string==null){
        	//将要缓存的数据
            List<BbsForumPostReturnVo> bbsForumPostReturnVos=bbsForumPostService.findPostByPage(vo);
            //存入缓存方法
            ValueOperations<String,String> vo2 = redisTemplate.opsForValue();
            Gson gson = new Gson();
            //通过set将数据存入缓存中,其中key为post
            vo2.set("post", gson.toJson(bbsForumPostReturnVos));
            Integer count=bbsForumPostService.findPostCount();
            Integer totalPage = (count+vo.getPageSize()-1)/vo.getPageSize();
            Map<String,Object> map=new HashMap<>();
            map.put("bbsForumPostReturnVos",bbsForumPostReturnVos==null?null:bbsForumPostReturnVos);
            map.put("totalCount",count);
            map.put("totalPage",totalPage);
            //Header.header(response);
            return ResultUtil.success(map);
        }else {
        	//将从缓存中取到的数据转为List
            List<BbsForumPostReturnVo> list = JSON.parseArray(string, BbsForumPostReturnVo.class);
            Integer count=bbsForumPostService.findPostCount();
            Integer totalPage = (count+vo.getPageSize()-1)/vo.getPageSize();
            Map<String,Object> map=new HashMap<>();
            map.put("bbsForumPostReturnVos",list==null?null:list);
            map.put("totalCount",count);
            map.put("totalPage",totalPage);
            //Header.header(response);
            return ResultUtil.success(map);
        }
    }
    }

4、通过Redis的key值获取缓存中的数据

//通过key获取缓存中的数据
String string = redisTemplate.opsForValue().get("post");
	//将从缓存中取到的数据转为List
 List<BbsForumPostReturnVo> list = JSON.parseArray(string, BbsForumPostReturnVo.class);

数据存入缓存中是以key-value的形式进行存储。

其中还可以通过注解的形式存储数据,@Cacheable注解可以加在接口、service以及controler中,当经过该注解的方法时,会自动将数据存入缓存中。具体@Cacheable的用法可以参考相关文档。

发布了55 篇原创文章 · 获赞 6 · 访问量 4007

猜你喜欢

转载自blog.csdn.net/qq_40126996/article/details/100839344