java操作Redis(jedis和lettuce)


一.使用Jedis

1.初始化項目

創建Maven項目並導入jedis依賴和我們需要使用的fastjson依賴

依賴可在Maven倉庫中搜索找到:https://search.maven.org/

 1         <!--jedis依賴-->
 2         <dependency>
 3             <groupId>redis.clients</groupId>
 4             <artifactId>jedis</artifactId>
 5             <version>3.2.0</version>
 6         </dependency>
 7         <!--fastjson-->
 8         <dependency>
 9             <groupId>com.alibaba</groupId>
10             <artifactId>fastjson</artifactId>
11             <version>1.2.62</version>
12         </dependency>
依賴

2.編程

1.測試連通

連接遠程服務器上的redis時,需要在配置文件中修改為相關配置使得允許遠程連接,若需要密碼授權也需要進行配置。

運行輸出 PONG,表示連通成功。

2.操作redis

jedis操作redis的方法就是redis的原生指令,幾乎沒有任何改變。

3.事務

 1 package com.kuang;
 2 
 3 import com.alibaba.fastjson.JSONObject;
 4 import redis.clients.jedis.Jedis;
 5 import redis.clients.jedis.Transaction;
 6 
 7 /**
 8  * @Description:
 9  * @author: ZYQ
10  * @date: 2020/10/18 17:18
11  */
12 public class tesetTX {
13     public static void main(String[] args) {
14         Jedis jedis = new Jedis("120.78.198.135", 6379);
15         jedis.auth("dhsqj.1982");
16 
17         JSONObject jsonObject = new JSONObject();
18         jsonObject.put("hello", "world");
19         jsonObject.put("name", "kuangshen");
20         String result = jsonObject.toJSONString();
21 
22         //開啟事務
23         Transaction multi = jedis.multi();
24         try {
25             //入隊 此時還未執行
26             multi.set("name", result);
27             multi.set("age", result);
28             //執行
29             multi.exec();
30             System.out.println(jedis.get("name"));
31             System.out.println(jedis.get("age"));
32         } catch (Exception e) {
33             multi.discard();
34             e.printStackTrace();
35         } finally {
36             jedis.close();
37         }
38     }
39 }
jedis寫事務

二.使用lettuce

1.初始化項目

新建SpringBoot項目,選擇redis依賴

1         <dependency>
2             <groupId>org.springframework.boot</groupId>
3             <artifactId>spring-boot-starter-data-redis</artifactId>
4         </dependency>
依賴

2.編寫配置文件

在SpringBoot2.x之后,redis依賴的底層實現用lettuce替換掉了jedis

jedis:采用的直連,多個線程操作的話,是不安全的;想要避免不安全,使用jedis pool連接池。更像BIO模式

lettuce:采用netty,實例可以在多個線程中共享,不存在線程不安全的情況;可以減少線程數量。更像NIO模式

源碼分析:

簡單配置一下

spring.redis.host=120.78.198.135
spring.redis.port=6379
spring.redis.password=dhsqj.1982

3.進行測試

 1 package com.example.demo;
 2 
 3 import org.junit.jupiter.api.Test;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.boot.test.context.SpringBootTest;
 6 import org.springframework.data.redis.connection.RedisConnection;
 7 import org.springframework.data.redis.core.RedisTemplate;
 8 
 9 @SpringBootTest
10 class DemoApplicationTests {
11 
12     @Autowired
13     private RedisTemplate redisTemplate;
14 
15     @Test
16     void contextLoads() {
17 
18         /**
19          * 獲取redis的連接對象象
20          */
21 //        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
22 //        connection.flushDb();
23 
24         /**
25          * opsForValue 操作String
26          * opsForList 操作list
27          * opsForSet 操作Set
28          * opsForHash 操作Hash
29          * opsForZset 操作Zset
30          * opsForGeo
31          * opsForHyperLogLog
32          */
33         redisTemplate.opsForValue().set("mykey", "kuangshen");
34         System.out.println(redisTemplate.opsForValue().get("mykey"));
35     }
36 
37 }
測試

發現僅在控制台上可以看到正確的結果,而在redis客戶端中查看到的序列化之后的結果是這樣的

點擊redisTemplate查看源碼

找到序列化默認的方式為jdk序列化方式,這種方式會將字符進行轉義,也就是上上圖看到的轉義之后的結果

通過redisTemplate上的conditionalOnMissingBean注解,表明我們可以通過自定義redisTemplate。

可以在自定義的redisTemplate中書寫序列化方法來覆蓋默認的序列化方法,從而解決這個轉義問題。

 


 

在未自定義redisTemplate之前,我們再進行測試來加深了解緣由

在pojo包中編寫一個最基礎的User對象,此時未進行序列化

在測試類中,嘗試直接將對象存儲在redis中,發現報錯,異常說明對象需要序列化

解決方法:在User類中實現序列化接口 Serializable 即可,默認的redisTemplate具有jdk序列化的具體實現,因此在redis中查看到的鍵值對依然為轉義的結果。

 接下來我們嘗試將對象轉化成json數據格式進行存儲並讀取

 發現結果如下,因為目前我們還沒有覆蓋默認的序列化方法

 


 

測試完畢,此時對redisTemplate序列化這方面有了一定的了解。接下來我們去自定義redisTemplate

 1 package com.example.demo.config;
 2 
 3 import com.fasterxml.jackson.annotation.JsonAutoDetect;
 4 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 5 import com.fasterxml.jackson.annotation.PropertyAccessor;
 6 import com.fasterxml.jackson.databind.ObjectMapper;
 7 import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
 8 import org.springframework.context.annotation.Bean;
 9 import org.springframework.context.annotation.Configuration;
10 import org.springframework.data.redis.connection.RedisConnectionFactory;
11 import org.springframework.data.redis.core.RedisTemplate;
12 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
13 import org.springframework.data.redis.serializer.StringRedisSerializer;
14 
15 /**
16  * @Description:
17  * @author: ZYQ
18  * @date: 2020/10/18 22:17
19  */
20 @Configuration
21 public class RedisConfig {
22 
23     @Bean
24     public RedisTemplate<String, Object> template(RedisConnectionFactory factory) {
25         RedisTemplate<String, Object> template = new RedisTemplate<>();
26         template.setConnectionFactory(factory);
27         //配置具體的序列化方法
28         Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
29         ObjectMapper om = new ObjectMapper();
30         om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
31         om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
32         jackson2JsonRedisSerializer.setObjectMapper(om);
33 
34         //String的序列化
35         StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
36         //key采用String的序列化方式
37         template.setKeySerializer(stringRedisSerializer);
38         //hash的key也采用String的序列化方式
39         template.setHashKeySerializer(stringRedisSerializer);
40         //value采用jackson序列化方式
41         template.setValueSerializer(jackson2JsonRedisSerializer);
42         //hash的value采用jackson序列化方式
43         template.setHashValueSerializer(jackson2JsonRedisSerializer);
44         template.afterPropertiesSet();
45         return template;
46     }
47 }
自定義redisTemplate

在測試中注入自定義的redisTemplate

    @Autowired
    @Qualifier("template")
    private RedisTemplate redisTemplate;

測試方法

注意:

1.pojo類可以不實現 Serialization 接口,自定義的jackson序列化會幫我們做好

2.pojo類必須有無參構造方法,否則會拋出異常

 運行后可以在redis客戶端中發現鍵值對符合我們的需求了

4.總結

 不管是jedis還是lettuce,其操作方法書寫起來都很簡單但繁瑣,我們可以自己去寫一個工具類來包裝一下常用的方法,使得代碼更簡潔。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM