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();
//最大連接數(shù),也就是線程池最多可以創(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() {
//存入數(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ù)操作的模塊,包含對各種數(shù)據(jù)庫的集成,其中對Redis的集成模塊就叫做SpringDataRedis。
- 提供了對不同Redis客戶端的整合(Lettuce和Jedis)
- 提供了RedisTemplate統(tǒng)一API來操作Redis
- 支持Redis的發(fā)布訂閱模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的響應式編程
- 支持基于JDK.JSON.字符串.Spring對象的數(shù)據(jù)序列化及反序列化
- 支持基于Redis的JDKCollection實現(xiàn)
(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ā)現(xiàn)一個問題,那就是我可以在Java代碼中set和get,取值都沒問題。但我如果在代碼中set,在命令端get,就會出現(xiàn)一堆看不懂的二進制,如下:

原因: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ā)現(xiàn)不管是key還是value,都已經(jīng)被我們自定義序列化。
(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的數(shù)據(jù)以外,還有個@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ù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java將GeoHash轉化為對應的經(jīng)緯度坐標實例代碼
這篇文章主要介紹了Java實現(xiàn)將GeoHash轉化為對應的經(jīng)緯度坐標的相關資料,需要的朋友可以參考下2016-01-01

