Redis?Java客戶端建立的兩種方式小結(jié)
第一種方式:Jedis方式
(1)引入依賴
<!--jedis--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.7.0</version> </dependency> <!--單元測(cè)試--> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.7.0</version> <scope>test</scope> </dependency>
(2)創(chuàng)建工廠類
public class JedisConnectionFactory { private static final JedisPool jedisPool; static { //配置連接池 JedisPoolConfig poolConfig = new JedisPoolConfig(); //最大連接數(shù),也就是線程池最多可以創(chuàng)建8個(gè)連接 poolConfig.setMaxTotal(8); //最大空閑連接 poolConfig.setMaxIdle(8); //最小空閑連接,超過(guò)一段時(shí)間后,如果一直沒(méi)有人訪問(wèn),空閑連接就會(huì)被釋放,直到為0為止 poolConfig.setMinIdle(0); //最大等待時(shí)間,如果超過(guò)1000毫秒,則報(bào)錯(cuò) poolConfig.setMaxWaitMillis(1000); //創(chuàng)建連接池對(duì)象 jedisPool = new JedisPool(poolConfig, "127.0.0.1",6379,1000,"123456"); } public static Jedis getJedis(){ return jedisPool.getResource(); } }
(3)創(chuàng)建Junit測(cè)試類
public class JedisTest { private Jedis jedis; @BeforeEach void setUp(){ //建立連接 jedis = JedisConnectionFactory.getJedis(); //選擇庫(kù) jedis.select(0); } @Test void testString() { //存入數(shù)據(jù) String result = jedis.set("name", "Jack"); System.out.println("result = " + result); // 獲取數(shù)據(jù) String name = jedis.get("name"); System.out.println("name = " + name); } @AfterEach void tearDown() { if (jedis != null) { jedis.close(); } } }
第二種方式:SpringDataRedis
SpringData是Spring中數(shù)據(jù)操作的模塊,包含對(duì)各種數(shù)據(jù)庫(kù)的集成,其中對(duì)Redis的集成模塊就叫做SpringDataRedis。
- 提供了對(duì)不同Redis客戶端的整合(Lettuce和Jedis)
- 提供了RedisTemplate統(tǒng)一API來(lái)操作Redis
- 支持Redis的發(fā)布訂閱模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的響應(yīng)式編程
- 支持基于JDK.JSON.字符串.Spring對(duì)象的數(shù)據(jù)序列化及反序列化
- 支持基于Redis的JDKCollection實(shí)現(xiàn)
(1)創(chuàng)建SpringBoot項(xiàng)目,選擇場(chǎng)景啟動(dòng)器
(2)引入依賴
<!--common-pool--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!--Jackson依賴--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency>
(3)配置application.yml
spring: redis: host: 127.0.0.1 port: 6379 password: 123456 lettuce: pool: max-active: 8 #最大連接 max-idle: 8 #最大空閑連接 min-idle: 0 #最小空閑連接 max-wait: 100ms #連接等待時(shí)間
(4)編寫(xiě)測(cè)試類
@SpringBootTest class SpringdataredisDemoApplicationTests { @Resource private RedisTemplate redisTemplate; @Test void testString() { redisTemplate.opsForValue().set("name","Tom"); Object name = redisTemplate.opsForValue().get("name"); System.out.println(name); //Tom } }
(5)序列化引起的問(wèn)題
我們這時(shí)可能會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,那就是我可以在Java代碼中set和get,取值都沒(méi)問(wèn)題。但我如果在代碼中set,在命令端get,就會(huì)出現(xiàn)一堆看不懂的二進(jìn)制,如下:
原因:RedisTemplate可以接收任意Object作為值寫(xiě)入Redis,只不過(guò)寫(xiě)入前會(huì)把Object序列化為字節(jié)形式,key也會(huì)被序列化為字節(jié)形式,默認(rèn)是采用JDK序列化。
因?yàn)檫@種序列化方式一是我們讀不懂,二是內(nèi)存占用較大。
所以我們要修改序列化方式,采用自定義的方式。
(6)創(chuàng)建自定義序列化配置類
@Configuration public class RedisConfig { @Bean @Resource public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){ // 創(chuàng)建RedisTemplate對(duì)象 RedisTemplate<String, Object> template = new RedisTemplate<>(); // 設(shè)置連接工廠 template.setConnectionFactory(connectionFactory); // 創(chuàng)建JSON序列化工具 GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); // 設(shè)置Key的序列化 template.setKeySerializer(RedisSerializer.string()); template.setHashKeySerializer(RedisSerializer.string()); // 設(shè)置Value的序列化 template.setValueSerializer(jsonRedisSerializer); template.setHashValueSerializer(jsonRedisSerializer); // 返回 return template; } }
(7)運(yùn)行測(cè)試類
我們發(fā)現(xiàn)不管是key還是value,都已經(jīng)被我們自定義序列化。
(8)測(cè)試一下對(duì)象存儲(chǔ)
@Data @NoArgsConstructor @AllArgsConstructor public class User { private String name; private Integer age; }
@Test void testSaveUser(){ redisTemplate.opsForValue().set("user:1",new User("Uzi",21)); User user = (User) redisTemplate.opsForValue().get("user:1"); System.out.println(user); }
注意:盡管JSON序列化可以滿足我們的需求,但仍然存在一些問(wèn)題,如上圖,除了我們set的數(shù)據(jù)以外,還有個(gè)@class,這是一筆不小的內(nèi)存開(kāi)銷(xiāo)啊,那么有方法可以解決嗎?
解決辦法:使用StringRedisTemplate
為了節(jié)省內(nèi)存空間,我們并不會(huì)使用JSON序列化器來(lái)處理value,而是統(tǒng)一使用String序列化器,要求只能存儲(chǔ)String類型的key和value。當(dāng)需要存儲(chǔ)Java對(duì)象時(shí),手動(dòng)完成對(duì)象的序列化和反序列化。
(9)新建測(cè)試類,使用StringRedisTemplate
@SpringBootTest public class RedisStringTests { @Resource private StringRedisTemplate stringRedisTemplate; //用來(lái)手動(dòng)序列化和反序列化,需引入Jackson包 private static final ObjectMapper mapper = new ObjectMapper(); @Test void testString() { stringRedisTemplate.opsForValue().set("name","Tom"); Object name = stringRedisTemplate.opsForValue().get("name"); System.out.println(name); } @Test void testSaveUser() throws JsonProcessingException { User user = new User("Uzi",21); //手動(dòng)序列化 String json = mapper.writeValueAsString(user); stringRedisTemplate.opsForValue().set("user:1",json); String jsonUser = stringRedisTemplate.opsForValue().get("user:1"); //手動(dòng)反序列化 User user1 = mapper.readValue(jsonUser, User.class); System.out.println(user1); } }
到此這篇關(guān)于Redis Java客戶端建立的兩種方式小結(jié)的文章就介紹到這了,更多相關(guān)Redis Java客戶端建立內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot項(xiàng)目POM文件的使用小結(jié)
本文主要詳細(xì)介紹了Maven中SpringBoot項(xiàng)目的POM文件配置,包括項(xiàng)目的依賴和插件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11純Java代碼實(shí)現(xiàn)流星劃過(guò)天空
本文給大家介紹純java代碼實(shí)現(xiàn)流星劃過(guò)天空,包括流星個(gè)數(shù),流星飛行的速度,色階,流星大小相關(guān)變量設(shè)置。對(duì)java流星劃過(guò)天空特效代碼感興趣的朋友可以參考下本文2015-10-10Session過(guò)期后實(shí)現(xiàn)自動(dòng)跳轉(zhuǎn)登錄頁(yè)面
這篇文章主要介紹了Session過(guò)期后實(shí)現(xiàn)自動(dòng)跳轉(zhuǎn)登錄頁(yè)面,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12詳解Java創(chuàng)建線程的五種常見(jiàn)方式
Java中如何進(jìn)行多線程編程,如何使用多線程?不要擔(dān)心,本文將為你詳細(xì)介紹一下Java實(shí)現(xiàn)線程創(chuàng)建的五種常見(jiàn)方式,感興趣的可以跟隨小編學(xué)習(xí)一下2022-01-01Java截取特定兩個(gè)標(biāo)記之間的字符串實(shí)例
下面小編就為大家?guī)?lái)一篇Java截取特定兩個(gè)標(biāo)記之間的字符串實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03Java將GeoHash轉(zhuǎn)化為對(duì)應(yīng)的經(jīng)緯度坐標(biāo)實(shí)例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)將GeoHash轉(zhuǎn)化為對(duì)應(yīng)的經(jīng)緯度坐標(biāo)的相關(guān)資料,需要的朋友可以參考下2016-01-01用SpringMVC編寫(xiě)一個(gè)HelloWorld的詳細(xì)過(guò)程
SpringMVC是Spring的一個(gè)后續(xù)產(chǎn)品,是Spring的一個(gè)子項(xiàng)目<BR>SpringMVC?是?Spring?為表述層開(kāi)發(fā)提供的一整套完備的解決方案,本文我們將用SpringMVC編寫(xiě)一個(gè)HelloWorld,文中有詳細(xì)的編寫(xiě)過(guò)程,需要的朋友可以參考下2023-08-08