zoukankan      html  css  js  c++  java
  • spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

    业务需求 首页 实现缓存分页 

    spring boot 整合redis   (我的是2.0.3版本的)

    在pom 文件写上依赖包即可 

    <dependency><!--依赖包-->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency> <dependency><!--设置reids配置需要的依赖包--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>

    在application.yml里面配置 相关的信息  如下图

    我是安装在本地windows上    host 127.0.0.1  安装在linux上需写上其IP地址

    这个时候 就可以使用redis 进行相关操作  

    redis相关操作(我这里懒得写) 请参考https://blog.csdn.net/xiaochunping9987/article/details/37900361 这篇博客

    但是使用 RedisTemplate 存List到redis 里面 get 一次就会消失     最后发现原因是没有对reids 进行相关设置 导致 redis的事务不一致 导致key 取一次就消失

    所以强烈建议 先进行redis 配置 在去使用redis 存数据

    配置类如下

    
    
    package com.wechat.config;
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    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.core.StringRedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;

    /**
    * @Auther: wxf
    * @Date: 2018/7/10 15:20
    */
    @Configuration
    @EnableCaching//开启注解
    public class RedisConfig {
    //缓存管理器 spring boot 2.0后 配置缓存管理器 和2.0以前 不一样 根据自己的版本 配置
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisTemplate) {
    return RedisCacheManager.create(redisTemplate);
    }
    // 以下两种redisTemplate自由根据场景选择
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);

    //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
    Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    serializer.setObjectMapper(mapper);

    template.setValueSerializer(serializer);
    //使用StringRedisSerializer来序列化和反序列化redis的key值
    template.setKeySerializer(new StringRedisSerializer());
    template.afterPropertiesSet();
         //这里设置redis事务一致
    template.setEnableTransactionSupport(true);
    return template;
    }
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
    StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
    stringRedisTemplate.setConnectionFactory(factory);
    stringRedisTemplate.setEnableTransactionSupport(true);
    return stringRedisTemplate;
    }
    }
     

    配置完后 就可以进行 reids 相关操作

    现在进行 redis的 list分页的相关操作  最后两个方法 是比较重要的

    
    
    package com.wechat.service;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.core.ValueOperations;
    import org.springframework.stereotype.Service;
    import javax.annotation.Resource;
    import java.util.List;
    /**
    * @Auther: wxf
    * @Date: 2018/7/4 16:43
    */
    @Service
    public class RedisService {
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Resource(name="stringRedisTemplate")
    ValueOperations<String, String> valOpsStr;

    @Autowired
    RedisTemplate<Object, Object> redisTemplate;
    @Resource(name = "redisTemplate")
    ValueOperations<Object, Object> valOpsObj;

    /**
    * 根据指定key获取String
    * @param key
    * @return
    */
    public String getStr(String key){
    String s = valOpsStr.get(key);

    if(s==null){
    return "暂无对应的值";
    }else{
    return s;
    }
    }
    /**
    * 设置Str缓存
    * @param key
    * @param val
    */
    public void setStr(String key, String val){
    valOpsStr.set(key,val);

    }
    /**
    * 删除指定key
    * @param key
    */

    public void del(String key){
    stringRedisTemplate.delete(key);
    }
    /**
    * 根据指定o获取Object
    * @param o
    * @return
    */
    public Object getObj(Object o) {
    Object o1 = valOpsObj.get(o);
    if(o1==null){
    return o1;
    }else{
    return o1;
    }
    }

    /**
    * 设置obj缓存
    * @param key
    * @param value
    */
    public void setObj(Object key, Object value){

    valOpsObj.set(key, value);
    }

    /**
    * 删除Obj缓存
    * @param o
    */
    public void delObj(Object o){
    redisTemplate.delete(o);
    }


    /** 添加对象到redis 里面的list中
    * redis中的 list 是双向的 所以添加的时候需要注意
    * rightPush 先进先出 leftPush 先进后出 这里 需要注意
    * @param key list 对应的key
    * @param obj 需要存的对象
    */
    public void addList(String key,Object obj){
    redisTemplate.opsForList().rightPush(key,obj);
    }


    /**
    * opsForList().range(key, start, end); 取范围值 redis里面的list下标从0开始
    * 流程 拿到key 对应的list 取 0 到 5 和 mysql的limt 类似 注意下标即可
    * 从redis list 里面的获取数据分页
    * @param key redis list 对应的key
    * @param start 开始下标
    * @param end 介绍下标
    * @return 返回list给前端
    */
    public List getListPage(String key, int start, int end){
    return (List)redisTemplate.opsForList().range(key, start, end);
    }
    }
     

    现在开始测试

    package com.wechat.controller;
    import com.wechat.dao.UserMapper;
    import com.wechat.pojo.User;
    import com.wechat.service.RedisService;
    import com.wechat.service.UserService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import java.util.List;
    
    /**
     * @Auther: wxf
     * @Date: 2018/6/28 10:21
     */
    @RestController
    @Slf4j
    public class TestContorller {
        @Autowired
        UserMapper userMapper;
        @Autowired
        UserService userService;
        @Autowired
        RedisService redisService;
    
        /**
         * 查询所有用户到redis中
         * @return
         */
        @RequestMapping("/test")
        public List<User> selectAll(){
            Object user1 = redisService.getObj("user");
            if(user1==null){
                List<User> users = userMapper.selectAll();
                redisService.setObj("user",users);
                log.info("没有缓存走数据库");
                return users;
            }else{
                List<User> listUser=(List)user1;
                log.info("有缓存");
                return listUser;
            }
        }
    
        /**
         * 我这里是把 user 信息存到object 中的  所有我要取出来用RedisTemplate 进行对 list的操作
         *
         */
        @RequestMapping("/add")
        public void addTest(){
            List<User> user = (List)redisService.getObj("user");
            for (User  u: user) {
                //这里循环user 把每个对象存到 redis中list中
                redisService.addList("list",u);
            }
    
        }
    
        /**
         * 这里取key 对应的list 那0 到 1 下标的 对象  也就是2个对象
         * @return
         */
        @RequestMapping("/aaa")
        public List aaa(){
            return redisService.getListPage("list",0,1);
        }
    
    
    }

    第一次 进test请求 前端截图如下

    后台 截图

    没有缓存  直接走的数据库读数据

    第二次请求 test

    数据一样的

    后台 不一样

    有缓存 现在 只想 add请求

    add没有返回值 所以 我们直接进redis 看

    redis 里面已经多了 key 为list 的list集合数据的数据

    可以看到 只有两条数据了 

    实现 动态的分页   第一次返回给前端总条数  让前端把或者后端把页码分出来 然后根据前端传过来的页码和一页几条 来动态取list的区间值 实现redis 分页

    总结 : spring boot 使用redis 很简单  但是 需要进行redis的相关配置和设置 不然就会出现 存一次 取一次 redis中的key 消失问题  

       redis 没有直接分页的方法 现在根据区间值来分页  或许还有更好的方法  知道的大佬 希望在下面留言 谢谢!!!!

  • 相关阅读:
    Spring MVC-表单(Form)标签-单选按钮(RadioButton)示例(转载实践)
    Ubuntu 16.04中VirtualBox 5.1使用U盘/USB设备的方法
    Spring MVC-表单(Form)标签-复选框集合(Checkboxes)示例(转载实践)
    Ubuntu 16.04下减小/释放/清理VirtualBox虚拟硬盘文件的大小
    关注点分离
    谈代码注释
    DelegatingFilterProxy类的作用
    GOPS 2018全球运维大会上海站 参会感悟梳理
    Java switch case
    Android 微信网址分享添加网络图片
  • 原文地址:https://www.cnblogs.com/wxf-com/p/9304254.html
Copyright © 2011-2022 走看看