Redis?Java客戶端建立的兩種方式小結
第一種方式:Jedis方式
(1)引入依賴
<!--jedis--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.7.0</version> </dependency> <!--單元測試--> <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(); //最大連接數,也就是線程池最多可以創(chuàng)建8個連接 poolConfig.setMaxTotal(8); //最大空閑連接 poolConfig.setMaxIdle(8); //最小空閑連接,超過一段時間后,如果一直沒有人訪問,空閑連接就會被釋放,直到為0為止 poolConfig.setMinIdle(0); //最大等待時間,如果超過1000毫秒,則報錯 poolConfig.setMaxWaitMillis(1000); //創(chuàng)建連接池對象 jedisPool = new JedisPool(poolConfig, "127.0.0.1",6379,1000,"123456"); } public static Jedis getJedis(){ return jedisPool.getResource(); } }
(3)創(chuàng)建Junit測試類
public class JedisTest { private Jedis jedis; @BeforeEach void setUp(){ //建立連接 jedis = JedisConnectionFactory.getJedis(); //選擇庫 jedis.select(0); } @Test void testString() { //存入數據 String result = jedis.set("name", "Jack"); System.out.println("result = " + result); // 獲取數據 String name = jedis.get("name"); System.out.println("name = " + name); } @AfterEach void tearDown() { if (jedis != null) { jedis.close(); } } }
第二種方式:SpringDataRedis
SpringData是Spring中數據操作的模塊,包含對各種數據庫的集成,其中對Redis的集成模塊就叫做SpringDataRedis。
- 提供了對不同Redis客戶端的整合(Lettuce和Jedis)
- 提供了RedisTemplate統(tǒng)一API來操作Redis
- 支持Redis的發(fā)布訂閱模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的響應式編程
- 支持基于JDK.JSON.字符串.Spring對象的數據序列化及反序列化
- 支持基于Redis的JDKCollection實現
(1)創(chuàng)建SpringBoot項目,選擇場景啟動器
(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 #連接等待時間
(4)編寫測試類
@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)序列化引起的問題
我們這時可能會發(fā)現一個問題,那就是我可以在Java代碼中set和get,取值都沒問題。但我如果在代碼中set,在命令端get,就會出現一堆看不懂的二進制,如下:
原因:RedisTemplate可以接收任意Object作為值寫入Redis,只不過寫入前會把Object序列化為字節(jié)形式,key也會被序列化為字節(jié)形式,默認是采用JDK序列化。
因為這種序列化方式一是我們讀不懂,二是內存占用較大。
所以我們要修改序列化方式,采用自定義的方式。
(6)創(chuàng)建自定義序列化配置類
@Configuration public class RedisConfig { @Bean @Resource public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){ // 創(chuàng)建RedisTemplate對象 RedisTemplate<String, Object> template = new RedisTemplate<>(); // 設置連接工廠 template.setConnectionFactory(connectionFactory); // 創(chuàng)建JSON序列化工具 GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); // 設置Key的序列化 template.setKeySerializer(RedisSerializer.string()); template.setHashKeySerializer(RedisSerializer.string()); // 設置Value的序列化 template.setValueSerializer(jsonRedisSerializer); template.setHashValueSerializer(jsonRedisSerializer); // 返回 return template; } }
(7)運行測試類
我們發(fā)現不管是key還是value,都已經被我們自定義序列化。
(8)測試一下對象存儲
@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序列化可以滿足我們的需求,但仍然存在一些問題,如上圖,除了我們set的數據以外,還有個@class,這是一筆不小的內存開銷啊,那么有方法可以解決嗎?
解決辦法:使用StringRedisTemplate
為了節(jié)省內存空間,我們并不會使用JSON序列化器來處理value,而是統(tǒng)一使用String序列化器,要求只能存儲String類型的key和value。當需要存儲Java對象時,手動完成對象的序列化和反序列化。
(9)新建測試類,使用StringRedisTemplate
@SpringBootTest public class RedisStringTests { @Resource private StringRedisTemplate stringRedisTemplate; //用來手動序列化和反序列化,需引入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); //手動序列化 String json = mapper.writeValueAsString(user); stringRedisTemplate.opsForValue().set("user:1",json); String jsonUser = stringRedisTemplate.opsForValue().get("user:1"); //手動反序列化 User user1 = mapper.readValue(jsonUser, User.class); System.out.println(user1); } }
到此這篇關于Redis Java客戶端建立的兩種方式小結的文章就介紹到這了,更多相關Redis Java客戶端建立內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!