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

其他

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