javascript
【第二十三篇】Spring Boot集成redis
1.1 簡介
REmote DIctionary Server(Redis)是一個由Salvatore Sanfilippo寫的key-value存儲系統(tǒng)。
Redis是一個開源的使用ANSI C語言編寫、遵守BSD協(xié)議、支持網絡、可基于內存亦可持久化的日志型、Key-Value數(shù)據庫,并提供多種語言的API。
它通常被稱為數(shù)據結構服務器,因為值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets)和 有序集合(sorted sets)等類型。
reids的優(yōu)點
- 異常快 - Redis非常快,每秒可執(zhí)行大約110000次的設置(SET)操作,每秒大約可執(zhí)行81000次的讀取/獲取(GET)操作。
- 支持豐富的數(shù)據類型 - Redis支持開發(fā)人員常用的大多數(shù)數(shù)據類型,例如列表,集合,排序集和散列等等。這使得Redis很容易被用來解決各種問題,因為我們知道哪些問題可以更好使用地哪些數(shù)據類型來處理解決。
- 操作具有原子性 - 所有Redis操作都是原子操作,這確保如果兩個客戶端并發(fā)訪問,Redis服務器能接收更新的值。
- 多實用工具 -Redis是一個多實用工具,可用于多種用例,如:緩存,消息隊列(Redis本地支持發(fā)布/訂閱),應用程序中的任何短期數(shù)據,例如,web應用程序中的會話,網頁命中計數(shù)等。
1.2 Redis 安裝
1.2.1 Linux安裝
本課程是在vmvare 虛擬機中來安裝的 redis (centos 7),學習的時候如果有自己的阿里云服務器,也可以在阿里云中來安裝redis,都可以。只要能 ping 的通云主機或者虛擬機的 ip,然后在虛擬機或者云主機中放行對應的端口(或者關掉防火墻)即可訪問 redis。下面來介紹一下 redis 的安裝過程:
1.2.1.1 安裝 gcc 編譯
因為后面安裝redis的時候需要編譯,所以事先得先安裝gcc編譯。阿里云主機已經默認安裝了 gcc,如果是自己安裝的虛擬機,那么需要先安裝一下gcc:
yum install gcc-c++1.2.1.2 下載redis
有兩種方式下載安裝包,一種是去官網上下載(https://redis.io),然后將安裝包拷到 centos中,另種方法是直接使用 wget來下載:
wget http://download.redis.io/releases/redis-3.2.8.tar.gz如果沒有安裝過 wget,可以通過如下命令安裝:
yum install wget1.2.1.3 解壓安裝
解壓安裝包:
tar –vzxf redis-3.2.8.tar.gz然后將解壓的文件夾redis-3.2.8放到 /usr/local/下,一般安裝軟件都放在/usr/local下。然后進入 /usr/local/redis-3.2.8/文件夾下,執(zhí)行 make 命令即可完成安裝。
【注】如果 make失敗,可以嘗試如下命令:
1.2.1.4 修改配置文件
安裝成功之后,需要修改一下配置文件,包括允許接入的ip,允許后臺執(zhí)行,設置密碼等等。
打開redis配置文件:vi redis.conf
在命令模式下輸入/bind來查找 bind配置,按n來查找下一個,找到配置后,將 bind配置成 0.0.0.0,允許任意服務器來訪問redis,即:
使用同樣的方法,將 daemonize改成yes(默認為no),允許redis在后臺執(zhí)行。
將 requirepass注釋打開,并設置密碼為 123456(密碼自己設置)。
1.2.1.5 啟動redis
在redis-3.2.8目錄下,指定剛剛修改好的配置文件redis.conf來啟動 redis:
redis-server ./redis.conf再啟動redis 客戶端:
redis-cli由于我們設置了密碼,在啟動客戶端之后,輸入 auth 123456即可登錄進入客戶端。
然后我們來測試一下,往 redis中插入一個數(shù)據:
然后來獲取 name
get name如果正常獲取到 CSDN,則說明沒有問題。
1.2.2 Windows安裝
下載地址:https://github.com/MSOpenTech/redis/releases
Redis 支持 32位和64位。這個需要根據你系統(tǒng)平臺的實際情況選擇,這里我們下載 Redis-x64-xxx.zip壓縮包到C盤,解壓后,將文件夾重新命名為redis。
打開一個 cmd窗口 使用cd命令切換目錄到C:\redis
運行 redis-server.exe redis.windows.conf
如果想方便的話,可以把redis的路徑加到系統(tǒng)的環(huán)境變量里,這樣就省得再輸路徑了,后面的那個 redis.windows.conf可以省略,如果省略,會啟用默認的。輸入之后,會顯示如下界面:
1.3 集成redis
Spring Boot對 redis的支持已經非常完善了,豐富的api 已經足夠我們日常的開發(fā)。
有兩個redis模板:RedisTemplate和 StringRedisTemplate。
RedisTemplate提供給我們操作對象,操作對象的時候,我們通常是以 json 格式存儲,但在存儲的時候,會使用 Redis默認的內部序列化器;導致我們存進里面的是亂碼之類的東西。當然了,我們可以自己定義序列化。
StringRedisTemplate主要給我們提供字符串操作,我們可以將實體類等轉成json 字符串即可,在取出來后,也可以轉成相應的對象,所以很有必要導入fastjson 的原因。
1.3.1 添加依賴
- 如果你的spring boot的版本號是1.4.0 到1.5.0之間,添加redis的jar包的時候 添加成 spring-boot-starter-data-redis 和 spring-boot-starter-redis 都是都可以的。
- 但是如果你的spring boot的版本號 是1.4.0以前 也就是1.3.8 版本以前,添加redis的jar包 就必須是spring-boot-starter-redis 的jar包。
- 如果你的spring boot的版本號在1.5.0以后的,添加redis的jar包就必須是spring-boot-starter-data-redis。
1.3.2 SpringBoot 1.4 整合redis
1.3.2.1 依賴
采用的是spring-boot-starter-redis,也可以添加成spring-boot-starter-data-redis
<!--集成redis--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-redis</artifactId><version>1.4.1.RELEASE</version> </dependency> <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.3</version> </dependency> <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId> </dependency>1.3.2.2 添加配置
spring.redis.host=127.0.0.1 #Redis服務器連接端口 spring.redis.port=6379 #Redis服務器連接密碼(默認為空) spring.redis.password= #連接池最大連接數(shù)(使用負值表示沒有限制) spring.redis.pool.max-active=8 #連接池最大阻塞等待時間(使用負值表示沒有限制) spring.redis.pool.max-wait=-1 #連接池中的最大空閑連接 spring.redis.pool.max-idle=8 #連接池中的最小空閑連接 spring.redis.pool.min-idle=0 #連接超時時間(毫秒) spring.redis.timeout=300001.3.2.3 配置類RedisConfig
@RefreshScope
動態(tài)配置刷新的我們要配置一個@RefreshScope在類上才可以實現(xiàn)對象屬性的的動態(tài)更新。
我們來總結下@RefreshScope實現(xiàn)流程
1、需要動態(tài)刷新的類標注@RefreshScope 注解
2、@RefreshScope 注解標注了@Scope注解,并默認了ScopedProxyMode.TARGET_CLASS; 屬性,此屬性的功能就是在創(chuàng)建一個代理,在每次調用的時候都用它來調用GenericScope get方法來獲取對象
3、如屬性發(fā)生變更會調用 ContextRefresher refresh() -》RefreshScope refreshAll()進行緩存清理方法調用,并發(fā)送刷新事件通知 -》GenericScope真正的 清理方法destroy()實現(xiàn)清理緩存
4、在下一次使用對象的時候,會調用GenericScope get(String name, ObjectFactory<?> objectFactory)方法創(chuàng)建一個新的對象,并存入緩存中,此時新對象因為Spring的裝配機制就是新的屬性了。
1.3.2.4 RedisUtils類
import java.io.Serializable; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.ListOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.SetOperations; import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; @Service public class RedisUtils {@Autowiredprivate RedisTemplate redisTemplate;/*** 寫入緩存* @param key* @param value* @return*/public boolean set(final String key, Object value) {boolean result = false;try {ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 寫入緩存設置時效時間* @param key* @param value* @return*/public boolean set(final String key, Object value, Long expireTime ,TimeUnit timeUnit) {boolean result = false;try {ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);redisTemplate.expire(key, expireTime, timeUnit);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 批量刪除對應的value* @param keys*/public void remove(final String... keys) {for (String key : keys) {remove(key);}}/*** 批量刪除key* @param pattern*/public void removePattern(final String pattern) {Set<Serializable> keys = redisTemplate.keys(pattern);if (keys.size() > 0){redisTemplate.delete(keys);}}/*** 刪除對應的value* @param key*/public void remove(final String key) {if (exists(key)) {redisTemplate.delete(key);}}/*** 判斷緩存中是否有對應的value* @param key* @return*/public boolean exists(final String key) {return redisTemplate.hasKey(key);}/*** 讀取緩存* @param key* @return*/public Object get(final String key) {Object result = null;ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();result = operations.get(key);return result;}/*** 哈希 添加* @param key* @param hashKey* @param value*/public void hmSet(String key, Object hashKey, Object value){HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();hash.put(key,hashKey,value);}/*** 哈希獲取數(shù)據* @param key* @param hashKey* @return*/public Object hmGet(String key, Object hashKey){HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();return hash.get(key,hashKey);}/*** 列表添加* @param k* @param v*/public void lPush(String k,Object v){ListOperations<String, Object> list = redisTemplate.opsForList();list.rightPush(k,v);}/*** 列表獲取* @param k* @param l* @param l1* @return*/public List<Object> lRange(String k, long l, long l1){ListOperations<String, Object> list = redisTemplate.opsForList();return list.range(k,l,l1);}/*** 集合添加* @param key* @param value*/public void add(String key,Object value){SetOperations<String, Object> set = redisTemplate.opsForSet();set.add(key,value);}/*** 集合獲取* @param key* @return*/public Set<Object> setMembers(String key){SetOperations<String, Object> set = redisTemplate.opsForSet();return set.members(key);}/*** 有序集合添加* @param key* @param value* @param scoure*/public void zAdd(String key,Object value,double scoure){ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();zset.add(key,value,scoure);}/*** 有序集合獲取* @param key* @param scoure* @param scoure1* @return*/public Set<Object> rangeByScore(String key,double scoure,double scoure1){ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();return zset.rangeByScore(key, scoure, scoure1);}1.3.2.5 測試controller
@RestController public class SpringBootController {public static final Logger log = LoggerFactory.getLogger(SpringBootController.class);@AutowiredTestService testService;@Autowiredprivate RedisUtils redisUtils;@RequestMapping(value = "/hello/{id}")public String hello(@PathVariable(value = "id") String id){//查詢緩存中是否存在boolean hasKey = redisUtils.exists(id);String str = "";if(hasKey){//獲取緩存Object object = redisUtils.get(id);log.info("從緩存獲取的數(shù)據"+ object);str = object.toString();}else{//從數(shù)據庫中獲取信息log.info("從數(shù)據庫中獲取數(shù)據");str = testService.test();//數(shù)據插入緩存(set中的參數(shù)含義:key值,user對象,緩存存在時間10(long類型),時間單位)redisUtils.set(id,str,10L,TimeUnit.MINUTES);log.info("數(shù)據插入緩存" + str);}return str;} }通過控制臺輸出,我們可以看到是從數(shù)據庫中獲取的數(shù)據,并且存入了redis緩存中。
可以看到,第二次是從緩存中讀取的,我們試試不斷刷新瀏覽器
可以看到,之后都是從緩存中獲取的。
1.3.3 SpringBoot 2.x整合redis
1.3.3.1 依賴
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.7.RELEASE</version><relativePath/> <!-- lookup parent from repository --> </parent> ......... <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>1.3.3.2 application.yml中加入redis依賴
spring:datasource:url: jdbc:mysql://localhost:3306/spring_cache?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMTdriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456redis:host: 39.107.250.174port: 6379database: 0timeout: 1000s # 數(shù)據庫連接超時時間,2.0 中該參數(shù)的類型為Duration,這里在配置的時候需要指明單位# 連接池配置,2.0中直接使用jedis或者lettuce配置連接池jedis:pool:# 最大空閑連接數(shù)max-idle: 500# 最小空閑連接數(shù)min-idle: 50# 等待可用連接的最大時間,負數(shù)為不限制max-wait: -1# 最大活躍連接數(shù),負數(shù)為不限制max-active: -1cache:redis:time-to-live: -1 #毫秒#以下可忽略 mybatis:configuration:#開啟駝峰命名map-underscore-to-camel-case: true logging:level:com.scitc.cache.mapper : debug1.3.3.3 redis配置類
package com.scitc.cache.config;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; 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.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; 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 java.time.Duration;@Configuration @EnableCaching//啟用緩存,這個注解很重要; //繼承CachingConfigurerSupport,為了自定義生成KEY的策略。可以不繼承。 public class RedisConfig extends CachingConfigurerSupport {@Value("${spring.cache.redis.time-to-live}")private Duration timeToLive = Duration.ZERO;@Bean(name = "redisTemplate")public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);//使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(mapper);template.setValueSerializer(jackson2JsonRedisSerializer);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();//使用StringRedisSerializer來序列化和反序列化redis的key值template.setKeySerializer(stringRedisSerializer);template.setKeySerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);//解決查詢緩存轉換異常的問題ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);// 配置序列化(解決亂碼的問題)RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(timeToLive).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}}然后我發(fā)現(xiàn)有好幾篇文章配置 CacheManager采用的是如下配置:
@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {// 生成一個默認配置,通過config對象即可對緩存進行自定義配置RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();// 設置緩存的默認過期時間,也是使用Duration設置config = config.entryTtl(Duration.ofMinutes(1)).disableCachingNullValues(); // 不緩存空值// 設置一個初始化的緩存空間set集合Set<String> cacheNames = new HashSet<>();cacheNames.add("my-redis-cache1");cacheNames.add("my-redis-cache2");// 對每個緩存空間應用不同的配置Map<String, RedisCacheConfiguration> configMap = new HashMap<>();configMap.put("my-redis-cache1", config);configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120)));// 使用自定義的緩存配置初始化一個cacheManagerRedisCacheManager cacheManager = RedisCacheManager.builder(factory).initialCacheNames(cacheNames) // 注意這兩句的調用順序,一定要先調用該方法設置初始化的緩存名,再初始化相關的配置.withInitialCacheConfigurations(configMap).build();return cacheManager;}但經過我使用測試發(fā)現(xiàn),他在redis中保存的數(shù)據是這樣的,并不是json
后面又找到一篇文章,重新配置 CacheManager (就是我直接貼出來的完整配置代碼)
經過測試訪問保存的數(shù)據格式為 json(下方有圖片)
到此配置完成,正常運行
1.3.3.4 RedisUtils工具類
package com.scitc.cache.utils;import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils;@Component public class RedisUtil {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 指定緩存失效時間* @param key 鍵* @param time 時間(秒)* @return*/public boolean expire(String key,long time){try {if(time>0){redisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根據key 獲取過期時間* @param key 鍵 不能為null* @return 時間(秒) 返回0代表為永久有效*/public long getExpire(String key){return redisTemplate.getExpire(key,TimeUnit.SECONDS);}/*** 判斷key是否存在* @param key 鍵* @return true 存在 false不存在*/public boolean hasKey(String key){try {return redisTemplate.hasKey(key);} catch (Exception e) {e.printStackTrace();return false;}}/*** 刪除緩存* @param key 可以傳一個值 或多個*/@SuppressWarnings("unchecked")public void del(String ... key){if(key!=null&&key.length>0){if(key.length==1){redisTemplate.delete(key[0]);}else{redisTemplate.delete(CollectionUtils.arrayToList(key));}}}//============================String=============================/*** 普通緩存獲取* @param key 鍵* @return 值*/public Object get(String key){return key==null?null:redisTemplate.opsForValue().get(key);}/*** 普通緩存放入* @param key 鍵* @param value 值* @return true成功 false失敗*/public boolean set(String key,Object value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 普通緩存放入并設置時間* @param key 鍵* @param value 值* @param time 時間(秒) time要大于0 如果time小于等于0 將設置無限期* @return true成功 false 失敗*/public boolean set(String key,Object value,long time){try {if(time>0){redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);}else{set(key, value);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 遞增* @param key 鍵* @param by 要增加幾(大于0)* @return*/public long incr(String key, long delta){if(delta<0){throw new RuntimeException("遞增因子必須大于0");}return redisTemplate.opsForValue().increment(key, delta);}/*** 遞減* @param key 鍵* @param by 要減少幾(小于0)* @return*/public long decr(String key, long delta){if(delta<0){throw new RuntimeException("遞減因子必須大于0");}return redisTemplate.opsForValue().increment(key, -delta);}//================================Map=================================/*** HashGet* @param key 鍵 不能為null* @param item 項 不能為null* @return 值*/public Object hget(String key,String item){return redisTemplate.opsForHash().get(key, item);}/*** 獲取hashKey對應的所有鍵值* @param key 鍵* @return 對應的多個鍵值*/public Map<Object,Object> hmget(String key){return redisTemplate.opsForHash().entries(key);}/*** HashSet* @param key 鍵* @param map 對應多個鍵值* @return true 成功 false 失敗*/public boolean hmset(String key, Map<String,Object> map){try {redisTemplate.opsForHash().putAll(key, map);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** HashSet 并設置時間* @param key 鍵* @param map 對應多個鍵值* @param time 時間(秒)* @return true成功 false失敗*/public boolean hmset(String key, Map<String,Object> map, long time){try {redisTemplate.opsForHash().putAll(key, map);if(time>0){expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一張hash表中放入數(shù)據,如果不存在將創(chuàng)建* @param key 鍵* @param item 項* @param value 值* @return true 成功 false失敗*/public boolean hset(String key,String item,Object value) {try {redisTemplate.opsForHash().put(key, item, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一張hash表中放入數(shù)據,如果不存在將創(chuàng)建* @param key 鍵* @param item 項* @param value 值* @param time 時間(秒) 注意:如果已存在的hash表有時間,這里將會替換原有的時間* @return true 成功 false失敗*/public boolean hset(String key,String item,Object value,long time) {try {redisTemplate.opsForHash().put(key, item, value);if(time>0){expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 刪除hash表中的值* @param key 鍵 不能為null* @param item 項 可以使多個 不能為null*/public void hdel(String key, Object... item){redisTemplate.opsForHash().delete(key,item);}/*** 判斷hash表中是否有該項的值* @param key 鍵 不能為null* @param item 項 不能為null* @return true 存在 false不存在*/public boolean hHasKey(String key, String item){return redisTemplate.opsForHash().hasKey(key, item);}/*** hash遞增 如果不存在,就會創(chuàng)建一個 并把新增后的值返回* @param key 鍵* @param item 項* @param by 要增加幾(大于0)* @return*/public double hincr(String key, String item,double by){return redisTemplate.opsForHash().increment(key, item, by);}/*** hash遞減* @param key 鍵* @param item 項* @param by 要減少記(小于0)* @return*/public double hdecr(String key, String item,double by){return redisTemplate.opsForHash().increment(key, item,-by);}//============================set=============================/*** 根據key獲取Set中的所有值* @param key 鍵* @return*/public Set<Object> sGet(String key){try {return redisTemplate.opsForSet().members(key);} catch (Exception e) {e.printStackTrace();return null;}}/*** 根據value從一個set中查詢,是否存在* @param key 鍵* @param value 值* @return true 存在 false不存在*/public boolean sHasKey(String key,Object value){try {return redisTemplate.opsForSet().isMember(key, value);} catch (Exception e) {e.printStackTrace();return false;}}/*** 將數(shù)據放入set緩存* @param key 鍵* @param values 值 可以是多個* @return 成功個數(shù)*/public long sSet(String key, Object...values) {try {return redisTemplate.opsForSet().add(key, values);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 將set數(shù)據放入緩存* @param key 鍵* @param time 時間(秒)* @param values 值 可以是多個* @return 成功個數(shù)*/public long sSetAndTime(String key,long time,Object...values) {try {Long count = redisTemplate.opsForSet().add(key, values);if(time>0) expire(key, time);return count;} catch (Exception e) {e.printStackTrace();return 0;}}/*** 獲取set緩存的長度* @param key 鍵* @return*/public long sGetSetSize(String key){try {return redisTemplate.opsForSet().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 移除值為value的* @param key 鍵* @param values 值 可以是多個* @return 移除的個數(shù)*/public long setRemove(String key, Object ...values) {try {Long count = redisTemplate.opsForSet().remove(key, values);return count;} catch (Exception e) {e.printStackTrace();return 0;}}//===============================list=================================/*** 獲取list緩存的內容* @param key 鍵* @param start 開始* @param end 結束 0 到 -1代表所有值* @return*/public List<Object> lGet(String key,long start, long end){try {return redisTemplate.opsForList().range(key, start, end);} catch (Exception e) {e.printStackTrace();return null;}}/*** 獲取list緩存的長度* @param key 鍵* @return*/public long lGetListSize(String key){try {return redisTemplate.opsForList().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 通過索引 獲取list中的值* @param key 鍵* @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數(shù)第二個元素,依次類推* @return*/public Object lGetIndex(String key,long index){try {return redisTemplate.opsForList().index(key, index);} catch (Exception e) {e.printStackTrace();return null;}}/*** 將list放入緩存* @param key 鍵* @param value 值* @param time 時間(秒)* @return*/public boolean lSet(String key, Object value) {try {redisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 將list放入緩存* @param key 鍵* @param value 值* @param time 時間(秒)* @return*/public boolean lSet(String key, Object value, long time) {try {redisTemplate.opsForList().rightPush(key, value);if (time > 0) expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 將list放入緩存* @param key 鍵* @param value 值* @param time 時間(秒)* @return*/public boolean lSet(String key, List<Object> value) {try {redisTemplate.opsForList().rightPushAll(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 將list放入緩存* @param key 鍵* @param value 值* @param time 時間(秒)* @return*/public boolean lSet(String key, List<Object> value, long time) {try {redisTemplate.opsForList().rightPushAll(key, value);if (time > 0) expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根據索引修改list中的某條數(shù)據* @param key 鍵* @param index 索引* @param value 值* @return*/public boolean lUpdateIndex(String key, long index,Object value) {try {redisTemplate.opsForList().set(key, index, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 移除N個值為value* @param key 鍵* @param count 移除多少個* @param value 值* @return 移除的個數(shù)*/public long lRemove(String key,long count,Object value) {try {Long remove = redisTemplate.opsForList().remove(key, count, value);return remove;} catch (Exception e) {e.printStackTrace();return 0;}} }1.3.3.5 自己遇到的問題
發(fā)現(xiàn)了個問題(不是配置文件的問題),我的對象實體類是這樣的
@Data public class Employee implements Serializable {private Integer id;private String lastName;private String email;private Integer gender; //性別 1男 0女 // private Integer userId;private Integer dId; }在json數(shù)據中多了一個did,
這次userId居然不重復,后面把dId換成了uId,依舊重復。。。
最開始不知道集成redis怎么在業(yè)務中使用,根據自己理解發(fā)現(xiàn),當你配置了redis,SpringBoot會自動把緩存加到redis中,并不使用默認的
@Cacheable(value = {"emp"},key = "#id")public Employee getEmp(Integer id){log.info("查詢" + id + "號員工");Employee employee = employeeMapper.getEmpById(id);return employee;}因為配置了redis所以使用redis緩存不使用默認的
總結
以上是生活随笔為你收集整理的【第二十三篇】Spring Boot集成redis的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ZTSF知多少?
- 下一篇: 【位运算】起床困难综合症(包含错误思路点