简单的使用redis存、取数据

  首先,redis配置类如下:

package org.jeecg.config;

import java.lang.reflect.Method;
import java.time.Duration;
import java.util.Arrays;

import javax.annotation.Resource;

import org.jeecg.common.constant.CacheConstant;
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.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
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 com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;

import static java.util.Collections.singletonMap;

@Configuration
@EnableCaching // 开启缓存支持
public class RedisConfig extends CachingConfigurerSupport {

   @Resource
   private LettuceConnectionFactory lettuceConnectionFactory;

// /**
//  * @description 自定义的缓存key的生成策略 若想使用这个key
//  *              只需要讲注解上keyGenerator的值设置为keyGenerator即可</br>
//  * @return 自定义策略生成的key
//  */
// @Override
// @Bean
// public KeyGenerator keyGenerator() {
//    return new KeyGenerator() {
//       @Override
//       public Object generate(Object target, Method method, Object... params) {
//          StringBuilder sb = new StringBuilder();
//          sb.append(target.getClass().getName());
//          sb.append(method.getDeclaringClass().getName());
//          Arrays.stream(params).map(Object::toString).forEach(sb::append);
//          return sb.toString();
//       }
//    };
// }

 /**
   * RedisTemplate配置
   *
   * @param lettuceConnectionFactory
    * @return
  */
 @Bean
 public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
      // 设置序列化
    Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
    ObjectMapper om = new ObjectMapper();
    om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
    om.enableDefaultTyping(DefaultTyping.NON_FINAL);
    jackson2JsonRedisSerializer.setObjectMapper(om);
    // 配置redisTemplate
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
    redisTemplate.setConnectionFactory(lettuceConnectionFactory);
    RedisSerializer<?> stringSerializer = new StringRedisSerializer();
    redisTemplate.setKeySerializer(stringSerializer);// key序列化
    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
    redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
    redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
 }

   /**
    * 缓存配置管理器
    *
    * @param factory
    * @return
    */
   @Bean
   public CacheManager cacheManager(LettuceConnectionFactory factory) {
        // 配置序列化(缓存默认有效期 6小时)
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6));
        RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                                                    .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

      // 以锁写入的方式创建RedisCacheWriter对象
      //RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
      // 创建默认缓存配置对象
      /* 默认配置,设置缓存有效期 1小时*/
      //RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));
      /* 自定义配置test:demo 的超时时间为 5分钟*/
      RedisCacheManager cacheManager = RedisCacheManager.builder(RedisCacheWriter.lockingRedisCacheWriter(factory)).cacheDefaults(redisCacheConfiguration)
            .withInitialCacheConfigurations(singletonMap(CacheConstant.TEST_DEMO_CACHE, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).disableCachingNullValues()))
            .transactionAware().build();
      return cacheManager;
   }
}

这个redisconfig配置类我是直接搬过来了,本章内容只用到了其中的redisTemplate方法.

一般也都会有对应的一个redisUtil类,redisUtil里面的方法也都是基于上面的redisconfig中的方法,

此处省略redisUtil中方法介绍;

redis的使用简单点来说就是先将数据存入redis,用到的时候再直接从redis中取所需的数据。在此处我举个例子,

目前需要一个基础数据(比如产品信息)的所有信息,类型是List<product>,也就是list实体,那么我就可以作如下操作:

先在productController中依赖注入RedisTemplate:
@Autowired
private RedisTemplate redisTemplate;

然后在该控制层的分页查询方法中将所有产品信息存入redis(也就是说,在产品信息页面加载的时候把所有数据存入redis,

当然,不局限于只加在这里):

@AutoLog(value = "产品-分页列表查询")
@ApiOperation(value="产品-分页列表查询", notes="产品-分页列表查询")
@GetMapping(value = "/list")
@TenantPermission
public Result<?> queryPageList(Product tProduct,
                        @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                        @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                        HttpServletRequest req) {
  //使用Mybatisplus中QueryWrapper查询
   QueryWrapper<Product> queryWrapper = QueryGenerator.initQueryWrapper(tProduct, req.getParameterMap());
   queryWrapper.eq("del_flag","1");
   Page<Product> page = new Page<Product>(pageNo, pageSize);
   IPage<Product> pageList = tProductService.page(page, queryWrapper);
  //判断一下是否有数据,这里的判断有点多余,但是由于没有数据并且不加判断直接使用会报错,所以这里加了一个判断
   if (this.tProductService.list(queryWrapper).size()>0){
      List<Product> productList = this.tProductService.list(queryWrapper);
      //把数据存入redis,不同仓库之间数据先要清空
      redisTemplate.delete("productList");
      redisTemplate.opsForList().rightPushAll("productList",productList);
   }else{
      redisTemplate.delete("productList");
   }
   return Result.ok(pageList);
}

在这里我是先用redisTemplate.delete方法删除缓存,再把查出的数据存入redis,因为所做系统

涉及到不同租户看到不同数据,所以查出数据的不同也会导致redis中数据不一样.

这样下来,向redis中存数据算是完成了.

接下来,从redis中取数据:

因为我存入redis的数据类型是list<product>,所以就用该类型接收,

List<Product> redisProductList = redisTemplate.boundListOps("productList").range(0,-1);

这里.range(0,-1)就是取所有数据,当然,如果只取前十条数据也可以写成.range(0,10),写成-1就是取所有.

本章内容是基于配置好的redis的存取数据,这里只是介绍了存取集合类型的数据,如果要存取其他类型可以看下底层方法.