這篇文章主要介紹了SpringBoot整合Redis案例分析的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇SpringBoot整合Redis案例分析文章都會有所收獲,下面我們一起來看看吧。
下載路徑cmd,然后redis-server.exe redis.windows.conf
命令既可以啟動服
在redis目錄下點擊redis-cli.exe進行測試結果查看,基本操作如下
key * :查看存儲內容
flushdb :清空數據庫
undefined
SpringData也是和SpringBoot齊名的項目!
說明:在SpringBoot2.x之后,原來使用的jedis被替換為了lettuce
jedis:采用的直連,多個線程操作的話,是不安全的,如果想要避免不安全的,使用jedis pool連接池!【類似于BIO:同步阻塞IO】
lettuce:采用netty【異步請求,性能更高點】,實例可以再多個線程中進行共享,不存在線程不安全的情況!可以減少線程數量了【類似于NIO:同步非阻塞IO】
異步請求一般都需要序列化
源碼分析:
源碼位置:
@Bean //當這個Bean不存在的時候,這個類就生效 //這就說明,我們可以自己定義一個redisTemplate來替換這個默認的! @ConditionalOnMissingBean(name = "redisTemplate") @ConditionalOnSingleCandidate(RedisConnectionFactory.class) public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { //默認的RedisTemplate沒有過多的設置,redis,對象都是需要序列化的! //兩個泛型都是Object類型,我們后面使用需要強制轉換:我們需要的類型<String, Object> RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean @ConditionalOnMissingBean //由于String是Redis最常用的類型,所以說單獨提出來了一個Bean @ConditionalOnSingleCandidate(RedisConnectionFactory.class) public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; }
<!--操作redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--上面redis不兼容時候,可以換成jedis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
# SpringBoot所有的配置類,都有一個自動配置類 RedisAutoConfiguration # 自動配置類都會綁定一個properties配置文件 RedisProperties spring: redis: host: 127.0.0.1 # Redis服務器連接端口 port: 6379 # Redis數據庫索引(默認為0) database: 0 # Redis服務器連接密碼(默認為空) password: # 連接池最大連接數(使用負值表示沒有限制) pool: max-active: 200 # 連接池最大阻塞等待時間(使用負值表示沒有限制) max-wait: -1 # 連接池中的最大空閑連接 max-idle: 10 # 連接池中的最小空閑連接 min-idle: 0 # 連接超時時間(毫秒) timeout: 1000
實際開發中我們都不會用這種原生的方式來編寫代碼
前面還有jdbcUtils和MybatisUtils等
@SpringBootTest class Redis03SpringbootApplicationTests { //注入RedisAutoConfiguration里面配置的類 @Autowired public RedisTemplate redisTemplate; @Test void contextLoads() { //redisTemplate :操作我們的數據庫,api和我們的是一樣的 //opsForValue :操作字符串 類似String //opsForList :操作List //除了基本的操作,我們常用的方法都可以直接通過redisTemplate進行操作 //比如事務和基本的CRUD //獲取redis的連接對象,就可以操作數據庫的連接了【一般很少來用】 /* RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); connection.flushDb(); connection.flushAll();*/ redisTemplate.opsForValue().set("kami", "g1x"); System.out.println(redisTemplate.opsForValue().get("kami")); } }
keys *
會出來亂碼這是默認的序列化配置
默認序列化方式是JDK序列化
自己寫了后,原來默認的RedisTemplate就會失效
創建一個config
@Configuration public class RedisConfig { //編寫我們自己的RedisTemplate @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); //這里面到底怎么配置看后面 template.setConnectionFactory(redisConnectionFactory); return template; } }
//將它變為組件,方便調用 @Component @Data @AllArgsConstructor @NoArgsConstructor public class User { private String name; private Integer age; }
@Test public void test() throws JsonProcessingException { //真實開發中一般都使用json來傳遞對象,所以要序列化json User user = new User("葛", 3); //所以要序列化成json對象【變成了json字符串】 String jsonUser = new ObjectMapper().writeValueAsString(user); redisTemplate.opsForValue().set("user", jsonUser); System.out.println(redisTemplate.opsForValue().get("user")); }
如果不用上面的序列化json對象操作會報錯!String jsonUser = new ObjectMapper().writeValueAsString(user);
下面是關于對象的保存,但是一般都是用json對象
//將它變為組件,方便調用 @Component @Data @AllArgsConstructor @NoArgsConstructor public class User implements Serializable { private String name; private Integer age; }
創建一個config
//這里面到底怎么配置看后面Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>();//配置具體的序列化template.setKeySerializer(objectJackson2JsonRedisSerializer);
多種序列化方式
寫法例子
自己寫很費勁,用已經寫好的例子即可
連接中有不同地方,復制連接中import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;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; import java.rmi.UnknownHostException; /** * @author zhangzhixi */@Configurationpublic class RedisConfig { @Bean @SuppressWarnings("all") public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { // 自定義 String Object RedisTemplate<String, Object> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); // Json 序列化配置 Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class); // ObjectMapper 轉譯 ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); objectJackson2JsonRedisSerializer.setObjectMapper(objectMapper); // String 的序列化 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key 采用String的序列化方式 template.setKeySerializer(stringRedisSerializer); // hash 的key也采用 String 的序列化方式 template.setHashKeySerializer(stringRedisSerializer); // value 序列化方式采用 jackson template.setValueSerializer(objectJackson2JsonRedisSerializer); // hash 的 value 采用 jackson template.setHashValueSerializer(objectJackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; }}
編寫工具類
package com.kami.utils;/** * @author zhangzhixi * @date 2021/3/1 23:33 */import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import org.springframework.util.CollectionUtils;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.TimeUnit;/** * @author mxz */@Componentpublic final class RedisUtil { @Autowired private 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 鍵(不能為 Null) * @return true 存在 false 不存在 */ public boolean hashKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 刪除緩存 * * @param key 可以傳一個值 或多個 */ public void del(String... key) { if (key != null && key.length > 0) { 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 delta 要增加幾(大于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 delta 要減少幾(小于0) * @return */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("遞減因子必須大于0"); } return redisTemplate.opsForValue().decrement(key, delta); } // ================================Map================================= /** * HashGet * * @param key 鍵 不能為null * @param item 項 不能為null */ 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 對應多個鍵值 */ 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表中放入數據,如果不存在將創建 * * @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表中放入數據,如果不存在將創建 * * @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遞增 如果不存在,就會創建一個 并把新增后的值返回 * * @param key 鍵 * @param item 項 * @param by 要增加幾(大于0) */ public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } /** * hash遞減 * * @param key 鍵 * @param item 項 * @param by 要減少記(小于0) */ public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } // ============================set============================= /** * 根據key獲取Set中的所有值 * * @param key 鍵 */ 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; } } /** * 將數據放入set緩存 * * @param key 鍵 * @param values 值 可以是多個 * @return 成功個數 */ public long sSet(String key, Object... values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 將set數據放入緩存 * * @param key 鍵 * @param time 時間(秒) * @param values 值 可以是多個 * @return 成功個數 */ 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 鍵 */ public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 移除值為value的 * * @param key 鍵 * @param values 值 可以是多個 * @return 移除的個數 */ 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代表所有值 */ 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 鍵 */ 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倒數第二個元素,依次類推 */ 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 值 */ 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 時間(秒) */ 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 值 * @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中的某條數據 * * @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 移除的個數 */ 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; } } // ===============================HyperLogLog================================= public long pfadd(String key, String value) { return redisTemplate.opsForHyperLogLog().add(key, value); } public long pfcount(String key) { return redisTemplate.opsForHyperLogLog().size(key); } public void pfremove(String key) { redisTemplate.opsForHyperLogLog().delete(key); } public void pfmerge(String key1, String key2) { redisTemplate.opsForHyperLogLog().union(key1, key2); }}
我們真實的分發中,或者在你們的公司,一般都可以看到一個公司自己封裝RedisUtil
轉到測試類
@SpringBootTestclass Redis02SpringbootApplicationTests { @Autowired // 指定我們自己定義的redis序列化配置 private RedisTemplate<String, Object> redisTemplate; @Autowired private RedisUtil redisUtil; @Test void test1() { // 清空數據庫 redisTemplate.getConnectionFactory().getConnection().flushDb(); User user = new User("zhangsha", 23); redisUtil.set("user", user); System.out.println(redisUtil.get("user")); }}
這時候注入的RedisTemplate
需要導入的是我們的
結果就是輸出前加了轉譯【不再是亂碼】
redis目錄中的redis-cle.exe
執行結果
關于“SpringBoot整合Redis案例分析”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“SpringBoot整合Redis案例分析”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。