SpringBoot2.0.X配置Redis

引入依赖

Lettuce

下面这种配置是使用 SpringBoot 默认 RedisClient,也就是 Lettuce

<!--Redis 1.X.X 使用 spring-boot-starter-redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <!-- sb2.x后,这个从 spring-boot-starter-redis 改成下面的-->
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- 集成redis连接池所需common-pool2,缺少了会报错 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

jedis

如果想使用 jedis,这样配置:

<!--Redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <!-- 必须要把lettuce移除掉,不让就算在application.yml中配置为jedis,也没效果 -->
    <exclusions>
        <exclusion>
            <artifactId>lettuce-core</artifactId>
            <groupId>io.lettuce</groupId>
        </exclusion>
    </exclusions>
</dependency>

<!--jedis - redis java 客户端-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

<!-- 集成redis连接池所需common-pool2,缺少了会报错 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

配置

application.yml

spring:
    # ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ redis基础配置  look -> SpringBoot2.0默认使用Redis连接池的配置注意事项:https://blog.csdn.net/ankeway/article/details/86544475 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ #
    # Redis 集群搭建 look -> Redis集群模式搭建与原理详解:https://juejin.im/post/5b8fc5536fb9a05d2d01fb11
    redis:
        # 集群配置,暂时注释掉,以后有用到解开注释即可
#        cluster:
#          nodes:
#            - 127.0.0.1:7001
#            - 127.0.0.1:7002
#            - 127.0.0.1:7003
#            - 127.0.0.1:7004
#            - 127.0.0.1:7005
#            - 127.0.0.1:7006
          # 获取失败 最大重定向次数
#          max-redirects: 3

      # Redis数据库索引(默认为0)
        database: 1
        # Redis服务器地址,使用集群请注释掉
        host: 127.0.0.1
        # Redis服务器地址,使用集群请注释掉
        port: 6379
        # Redis服务器连接密码(默认为空)
        password: 111111
        # 连接超时时间(毫秒)
        timeout: 3000000s
        lettuce:
            # 关闭超时时间
            shutdown-timeout: 100s
            ## redis线程池设置
            pool:
                # 连接池最大连接数(使用负值表示没有限制)
                max-active: 8
                # 连接池中的最大空闲连接
                max-idle: 8
                # 连接池最大阻塞等待时间(使用负值表示没有限制)
                max-wait: 1000000s
                # 连接池中的最小空闲连接
                min-idle: 1
         # jedis,如何你想使用jedis,则注释上面的Lettuce,打开这个注释即可
#        jedis:
#            pool:
#                # 连接池最大连接数(使用负值表示没有限制)
#                max-active: 8
#                # 连接池最大阻塞等待时间
#                max-wait: 1000000s
#                # 连接池中的最大空闲连接
#                max-idle: 8
#                # 连接池中的最小空闲连接
#                min-idle: 1

RedisConfig.java

package com.blog.www.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * Redis配置
 * <p>
 * 创建人:leigq <br>
 * 创建时间:2018-11-08 10:11 <br>
 * <p>
 * 修改人: <br>
 * 修改时间: <br>
 * 修改备注: <br>
 * </p>
 */
@Configuration
public class RedisConfig {

    /**
     * 使用 JacksonConfig 中的 objMapper,兼容 java8 时间
     *
     * @see JacksonConfig#getObjMapper()
     */
    private final ObjectMapper objMapper;

    public RedisConfig(@Qualifier(value = "objMapper") ObjectMapper objMapper) {
        this.objMapper = objMapper;
    }

    /**
     * redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类, 生产环境不建议这样
     * <br/>
     * 参考:https://blog.csdn.net/m0_37893932/article/details/78259288
     * <br>创建人: leigq
     * <br>创建时间: 2018-11-08 10:12
     * <br>
     *
     * @param redisConnectionFactory redis连接工厂
     * @return RedisTemplate
     */
    @Bean(value = "redisTemp")
    @Primary
    public RedisTemplate<Object, Object> getRedisTemplate(RedisConnectionFactory redisConnectionFactory) {

        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        objMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objMapper);

        // 以下代码为将 RedisTemplate 的 Value 序列化方式由 JdkSerializationRedisSerializer更换为 Jackson2JsonRedisSerializer
        // 此种序列化方式结果清晰、容易阅读、存储字节少、速度快,所以推荐更换
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // 设置 key 的序列化规则
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        // 是否启用事务
//		redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;

    }
}

上面使用到的 objMapper 源码:

JacksonConfig.java, 添加 java8 时间支持

package com.blog.www.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

/**
 * ObjectMapper配置,在使用 ObjectMapper 的地方,方便直接注入 ObjectMapper 进行使用,
 * 但是推荐统一使用 {@link com.blog.www.util.JSONUtils} 工具类
 */
@Configuration
public class JacksonConfig {

	@Bean(name = "objMapper")
	@Primary
	public ObjectMapper getObjMapper() {
		ObjectMapper objectMapper = new ObjectMapper();

		// objectMapper.configure() 方法与 objectMapper.disable(), objectMapper.enable() 作用一样,
		// 都是进行一些配置,查看源码得知:都是调用 _serializationConfig.without(f) 方法
		/*禁用一些配置*/
		// 时间项目推荐返回前端时间戳,前端根据需要自己转换格式
//        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

		/*启用一些配置*/
		objectMapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);

		/*时间模块*/
        JavaTimeModule javaTimeModule = new JavaTimeModule();
		/*序列化配置, 针对java8 时间*/
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));

		/*反序列化配置, 针对java8 时间*/
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));

		/*注册模块*/
		objectMapper
                .registerModule(javaTimeModule)
				.registerModule(new Jdk8Module())
				.registerModule(new ParameterNamesModule());

		// 属性命名策略
		objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
		// 时区
		objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
		// 时间格式
		objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		return objectMapper;
	}
}

工具类

RedisUtils.java

package com.blog.www.util;

import com.blog.www.config.RedisConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;


/**
 * 基于 spring 和 redis 的 redisTemplate 工具类
 * <br/>
 * 针对所有的 hash 都是以 h 开头的方法
 * <br/>
 * 针对所有的 Set 都是以 s 开头的方法
 * <br/>
 * 不含通用方法
 * <br/>
 * 参考:<br/>
 * <ul>
 *     <li>
 *         <a href='https://blog.csdn.net/varyall/article/details/88785104'>Redis的三个框架:Jedis,Redisson,Lettuce</a>
 *     </li>
 *     <li>
 *         <a href='https://blog.csdn.net/chineseyoung/article/details/80972231'>Redis工具类(基于spring boot)</a>
 *     </li>
 * </ul>
 * <p>
 * 创建人:leigq <br>
 * 创建时间:2018-11-07 17:48 <br>
 * <p>
 * 修改人: <br>
 * 修改时间: <br>
 * 修改备注: <br>
 * </p>
 */
@Service
@Slf4j
@SuppressWarnings(value = "unchecked")
public final class RedisUtils {

	// 这个是关键↓↓↓
	private final RedisTemplate redisTemp;

	/**
	 * 使用 RedisConfig 中的 redisTemp,自定义序列化 及 兼容 java8 时间
	 * @see RedisConfig#getRedisTemplate(RedisConnectionFactory)
	 */
	public RedisUtils(@Qualifier(value = "redisTemp") RedisTemplate redisTemp) {
		this.redisTemp = redisTemp;
	}

	//=============================common============================

	/**
	 * 指定对应Key的缓存失效时间
	 *
	 * @param key  键
	 * @param time 时间(秒)
	 * @return 结果
	 */
	public boolean expire(String key, long time) {
		try {
			return redisTemp.expire(key, time, TimeUnit.SECONDS);
		} catch (Exception e) {
			log.error("指定对应Key的缓存失效时间异常:", e);
			return false;
		}
	}

	/**
	 * 根据key获取过期时间
	 *
	 * @param key 键 不能为null
	 * @return 时间(秒) 返回0代表为永久有效 失效时间为负数,说明该主键未设置失效时间(失效时间默认为-1)
	 */
	public long getExpire(String key) {
		return redisTemp.getExpire(key, TimeUnit.SECONDS);
	}

	/**
	 * 判断key是否存在
	 *
	 * @param key 键
	 * @return true 存在 false 不存在
	 */
	public boolean hasKey(String key) {
		try {
			return redisTemp.hasKey(key);
		} catch (Exception e) {
			log.error("判断key是否存在异常:", e);
			return false;
		}
	}

	/**
	 * 删除缓存
	 *
	 * @param key 可以传一个值 或多个
	 */
	public void del(String... key) {
		if (key != null && key.length > 0) {
			if (key.length == 1) {
				redisTemp.delete(key[0]);
			} else {
				redisTemp.delete(CollectionUtils.arrayToList(key));
			}
		}
	}

	//============================String=============================

	/**
	 * 普通缓存获取
	 *
	 * @param key 键
	 * @return 值
	 */
	public Object getStr(String key) {
		return key == null ? null : redisTemp.opsForValue().get(key);
	}

	/**
	 * 普通缓存放入
	 *
	 * @param key   键
	 * @param value 值
	 * @return true成功 false失败
	 */
	public boolean setStr(String key, Object value) {
		try {
			redisTemp.opsForValue().set(key, value);
			return true;
		} catch (Exception e) {
			log.error("普通缓存放入异常:", e);
			return false;
		}

	}

	/**
	 * 普通缓存放入并设置时间
	 *
	 * @param key   键
	 * @param value 值
	 * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
	 * @return true成功 false 失败
	 */
	public boolean setStr(String key, Object value, long time) {
		try {
			if (time > 0) {
				redisTemp.opsForValue().set(key, value, time, TimeUnit.SECONDS);
			} else {
				setStr(key, value);
			}
			return true;
		} catch (Exception e) {
			log.error("普通缓存放入并设置时间异常:", e);
			return false;
		}
	}

	/**
	 * 递增 此时value值必须为int类型 否则报错
	 *
	 * @param key   键
	 * @param delta 要增加几(大于0)
	 * @return 执行递增操作后key对应的值
	 */
	public long incr(String key, long delta) {
		if (delta < 0) {
			throw new RuntimeException("递增因子必须大于0");
		}
		return redisTemp.opsForValue().increment(key, delta);
	}

	/**
	 * 递减
	 *
	 * @param key   键
	 * @param delta 要减少几(小于0)
	 * @return 执行递减操作后key对应的值
	 */
	public long decr(String key, long delta) {
		if (delta < 0) {
			throw new RuntimeException("递减因子必须大于0");
		}
		return redisTemp.opsForValue().increment(key, -delta);
	}

	//================================Map=================================

	/**
	 * HashGet
	 *
	 * @param key  键 不能为null
	 * @param item 项 不能为null
	 * @return 值
	 */
	public Object hGet(String key, String item) {
		return redisTemp.opsForHash().get(key, item);
	}

	/**
	 * 获取hashKey对应的所有键值
	 *
	 * @param key 键
	 * @return 对应的多个键值
	 */
	public Map<Object, Object> hMGet(String key) {
		return redisTemp.opsForHash().entries(key);
	}

	/**
	 * HashSet缓存放入
	 *
	 * @param key 键
	 * @param map 对应多个键值
	 * @return true 成功 false 失败
	 */
	public boolean hMSet(String key, Map<String, Object> map) {
		try {
			redisTemp.opsForHash().putAll(key, map);
			return true;
		} catch (Exception e) {
			log.error("HashSet缓存放入异常:", e);
			return false;
		}
	}

	/**
	 * HashSet 缓存放入并设置时间
	 *
	 * @param key  键
	 * @param map  对应多个键值
	 * @param time 时间(秒)
	 * @return true成功 false失败
	 */
	public boolean hMSet(String key, Map<String, Object> map, long time) {
		try {
			redisTemp.opsForHash().putAll(key, map);
			if (time > 0) {
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			log.error("HashSet 缓存放入并设置时间异常:", e);
			return false;
		}
	}

	/**
	 * 向一张hash表中放入数据,如果不存在将创建
	 *
	 * @param key   键
	 * @param item  项
	 * @param value 值
	 * @return true 成功 false失败
	 */
	public boolean hSet(String key, String item, Object value) {
		try {
			redisTemp.opsForHash().put(key, item, value);
			return true;
		} catch (Exception e) {
			log.error("向一张hash表中放入数据,如果不存在将创建异常:", e);
			return false;
		}
	}

	/**
	 * 向一张hash表中放入数据,如果不存在将创建并设置时间
	 *
	 * @param key   键
	 * @param item  项
	 * @param value 值
	 * @param time  时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间
	 * @return true 成功 false失败
	 */
	public boolean hSet(String key, String item, Object value, long time) {
		try {
			redisTemp.opsForHash().put(key, item, value);
			if (time > 0) {
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			log.error("向一张hash表中放入数据,如果不存在将创建并设置时间异常:", e);
			return false;
		}
	}

	/**
	 * 删除hash表中的值
	 *
	 * @param key  键 不能为null
	 * @param item 项 可以使多个 不能为null
	 */
	public void hDel(String key, Object... item) {
		redisTemp.opsForHash().delete(key, item);
	}

	/**
	 * 判断hash表中是否有该项的值
	 *
	 * @param key  键 不能为null
	 * @param item 项 不能为null
	 * @return true 存在 false不存在
	 */
	public boolean hHasKey(String key, String item) {
		return redisTemp.opsForHash().hasKey(key, item);
	}

	/**
	 * hash递增 如果不存在,就会创建一个 并把新增后的值返回
	 *
	 * @param key  键
	 * @param item 项
	 * @param by   要增加几(大于0)
	 * @return 执行递增操作后key对应的值
	 */
	public double hIncr(String key, String item, double by) {
		return redisTemp.opsForHash().increment(key, item, by);
	}

	/**
	 * hash递减
	 *
	 * @param key  键
	 * @param item 项
	 * @param by   要减少记(小于0)
	 * @return 执行递减操作后key对应的值
	 */
	public double hDecr(String key, String item, double by) {
		return redisTemp.opsForHash().increment(key, item, -by);
	}

	//============================set=============================

	/**
	 * 根据key获取Set中的所有值
	 *
	 * @param key 键
	 * @return Set中的所有值
	 */
	public Set<Object> sGet(String key) {
		try {
			return redisTemp.opsForSet().members(key);
		} catch (Exception e) {
			log.error("根据key获取Set中的所有值异常:", e);
			return null;
		}
	}

	/**
	 * 根据value从一个set中查询,是否存在
	 *
	 * @param key   键
	 * @param value 值
	 * @return true 存在 false不存在
	 */
	public boolean sHasKey(String key, Object value) {
		try {
			return redisTemp.opsForSet().isMember(key, value);
		} catch (Exception e) {
			log.error("根据value从一个set中查询,是否存在异常:", e);
			return false;
		}
	}

	/**
	 * 将数据放入set缓存
	 *
	 * @param key    键
	 * @param values 值 可以是多个
	 * @return 成功个数
	 */
	public long sSet(String key, Object... values) {
		try {
			return redisTemp.opsForSet().add(key, values);
		} catch (Exception e) {
			log.error("将数据放入set缓存异常:", e);
			return 0;
		}
	}

	/**
	 * 将set数据放入缓存
	 *
	 * @param key    键
	 * @param time   时间(秒)
	 * @param values 值 可以是多个
	 * @return 成功个数
	 */
	public long sSetAndTime(String key, long time, Object... values) {
		try {
			Long count = redisTemp.opsForSet().add(key, values);
			if (time > 0) {
				expire(key, time);
			}
			return count;
		} catch (Exception e) {
			log.error("将set数据放入缓存异常:", e);
			return 0;
		}
	}

	/**
	 * 获取set缓存的长度
	 *
	 * @param key 键
	 * @return 长度
	 */
	public long sGetSetSize(String key) {
		try {
			return redisTemp.opsForSet().size(key);
		} catch (Exception e) {
			log.error("获取set缓存的长度异常:", e);
			return 0;
		}
	}

	/**
	 * 移除值为value的
	 *
	 * @param key    键
	 * @param values 值 可以是多个
	 * @return 移除的个数
	 */
	public long setRemove(String key, Object... values) {
		try {
			Long count = redisTemp.opsForSet().remove(key, values);
			return count;
		} catch (Exception e) {
			log.error("移除值为value的异常:", e);
			return 0;
		}
	}
	//===============================list=================================

	/**
	 * 获取list缓存的内容
	 *
	 * @param key   键
	 * @param start 开始
	 * @param end   结束  0 到 -1代表所有值
	 * @return list缓存
	 */
	public List<Object> lGet(String key, long start, long end) {
		try {
			return redisTemp.opsForList().range(key, start, end);
		} catch (Exception e) {
			log.error("获取list缓存的内容异常:", e);
			return null;
		}
	}

	/**
	 * 获取list缓存的长度
	 *
	 * @param key 键
	 * @return 长度
	 */
	public long lGetListSize(String key) {
		try {
			return redisTemp.opsForList().size(key);
		} catch (Exception e) {
			log.error("获取list缓存的长度异常:", e);
			return 0;
		}
	}

	/**
	 * 通过索引 获取list中的值
	 *
	 * @param key   键
	 * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
	 * @return 值
	 */
	public Object lGetIndex(String key, long index) {
		try {
			return redisTemp.opsForList().index(key, index);
		} catch (Exception e) {
			log.error("通过索引 获取list中的值异常:", e);
			return null;
		}
	}

	/**
	 * 将list放入缓存
	 *
	 * @param key   键
	 * @param value 值
	 * @return if success return true else return false
	 */
	public boolean lSet(String key, Object value) {
		try {
			redisTemp.opsForList().rightPush(key, value);
			return true;
		} catch (Exception e) {
			log.error("将list放入缓存异常:", e);
			return false;
		}
	}

	/**
	 * 将list放入缓存并设置过期时间
	 *
	 * @param key   键
	 * @param value 值
	 * @param time  时间(秒)
	 * @return if success return true else return false
	 */
	public boolean lSet(String key, Object value, long time) {
		try {
			redisTemp.opsForList().rightPush(key, value);
			if (time > 0) {
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			log.error("将list放入缓存并设置过期时间异常:", e);
			return false;
		}
	}

	/**
	 * 将list放入缓存
	 *
	 * @param key   键
	 * @param value 值
	 * @return if success return true else return false
	 */
	public boolean lSet(String key, List<Object> value) {
		try {
			redisTemp.opsForList().rightPushAll(key, value);
			return true;
		} catch (Exception e) {
			log.error("将list放入缓存异常:", e);
			return false;
		}
	}

	/**
	 * 将list放入缓存并设置过期时间
	 *
	 * @param key   键
	 * @param value 值
	 * @param time  时间(秒)
	 * @return if success return true else return false
	 */
	public boolean lSet(String key, List<Object> value, long time) {
		try {
			redisTemp.opsForList().rightPushAll(key, value);
			if (time > 0) {
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			log.error("将list放入缓存并设置过期时间异常:", e);
			return false;
		}
	}

	/**
	 * 根据索引修改list中的某条数据
	 *
	 * @param key   键
	 * @param index 索引
	 * @param value 值
	 * @return if success return true else return false
	 */
	public boolean lUpdateIndex(String key, long index, Object value) {
		try {
			redisTemp.opsForList().set(key, index, value);
			return true;
		} catch (Exception e) {
			log.error("根据索引修改list中的某条数据异常:", e);
			return false;
		}
	}

	/**
	 * 移除N个值为value
	 *
	 * @param key   键
	 * @param count 移除多少个
	 * @param value 值
	 * @return 移除的个数
	 */
	public long lRemove(String key, long count, Object value) {
		try {
			return redisTemp.opsForList().remove(key, count, value);
		} catch (Exception e) {
			log.error("移除N个值为value异常:", e);
			return 0;
		}
	}

}

测试

RedisUtilsTest.java

package com.blog.www;

import com.blog.www.base.BaseApplicationTests;
import com.blog.www.bean.CacheUser;
import com.blog.www.domain.entity.User;
import com.blog.www.util.JSONUtils;
import com.blog.www.util.RedisUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * 自己RedisUtil测试
 * <p>
 * 创建人:leigq <br>
 * 创建时间:2018-12-08 14:48 <br>
 * <p>
 * 修改人: <br>
 * 修改时间: <br>
 * 修改备注: <br>
 * </p>
 */
public class RedisUtilsTest extends BaseApplicationTests {

    @Autowired
    private RedisUtils redisUtils;

    @Test
    public void redisTest() throws JsonProcessingException {
        User user = new User();
        user.setAge((short) 10);
        user.setUserName("121212");

        String s = JSONUtils.obj2json(user);
        log.warn("user入库前 --> [{}]", s);

        String key = "user";
        redisUtils.setStr(key, s, 60 * 3);
        log.warn("user入库后,回查 --> [{}]", redisUtils.getStr(key));

        // java8 时间测试 -- 测试通过
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();

        log.warn("localDateTime 入库前 --> [{}]", localDateTime);
        log.warn("localDate 入库前 --> [{}]", localDate);
        log.warn("localTime 入库前 --> [{}]", localTime);

        String localDateTimeKey = "localDateTime";
        redisUtils.setStr(localDateTimeKey, localDateTime, 60 * 3);

        String localDateKey = "localDate";
        redisUtils.setStr(localDateKey, localDate, 60 * 3);

        String localTimeKey = "localTime";
        redisUtils.setStr(localTimeKey, localTime, 60 * 3);

        log.warn("localDateTime 入库后,回查 --> [{}]", redisUtils.getStr(localDateTimeKey));
        log.warn("localDate 入库后,回查 --> [{}]", redisUtils.getStr(localDateKey));
        log.warn("localTime 入库后,回查 --> [{}]", redisUtils.getStr(localTimeKey));
    }
}

BaseApplicationTests.java

package com.blog.www.base;

import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * 测试基类,其他类继承此类
 * <br/>
 * @author     :leigq
 * @date       :2019/8/13 17:17
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public abstract class BaseApplicationTests {

    protected Logger log = LoggerFactory.getLogger(this.getClass());

    private Long time;

    @Before
    public void setUp() {
        this.time = System.currentTimeMillis();
        log.info("==> 测试开始执行 <==");
    }

    @After
    public void tearDown() {
        log.info("==> 测试执行完成,耗时:{} ms <==", System.currentTimeMillis() - this.time);
    }
}

测试结果:

20191018103250.png

20191018103404.png

其他

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章