Spring Data Redis 管理Redis 之1

redis是一款非常流行的Nosql,提供的功能非常強大,本節不再贅述。

本文簡單介紹Spring Data框架提供的spring_data_redis模塊,所提供的強大功能。雖然,spring_data_redis不具體負責與redis通信,但提供了豐富的外圍功能。

主要包含以下內容

  1. 搭建測試環境

  2. 序列工具

  3. 認識RedisConnectionFactory&RedisTemplate

1.搭建測試環境

1.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <!-- Your own application should inherit from spring-boot-starter-parent -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.5.RELEASE</version>
    </parent>
    <groupId>com.hellodb.springdata</groupId>
    <artifactId>redisdemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
        </dependency>
        <!-- 客戶端 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
                    <groupId>biz.paluch.redis</groupId>
                    <artifactId>lettuce</artifactId>
                    <version>3.2.Final</version>
        </dependency>
        <!--序列化工具 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies> 
</project>

1.2配置XML

jedis-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

       <!-- Jedis ConnectionFactory -->
       <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
              p:port="6379" p:hostName="192.168.163.146"/>

       <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
              <property name="connectionFactory" ref="jedisConnectionFactory"></property>
       </bean>
</beans>

lettuce-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

       <!-- Jedis ConnectionFactory -->
       <bean id="lettuceConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"
              p:port="6379" p:hostName="192.168.163.146"/>

       <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
              <property name="connectionFactory" ref="lettuceConnectionFactory"></property>
       </bean>
</beans>

實際環境中,只需要選擇一個客戶端即可。當然,各個客戶端的使用場景有所區別,這兒就不深入討論了。

JedisRedisTemplateTest.java :使用jedis客戶端

@RunWith(SpringJUnit4Cla***unner.class)
@ContextConfiguration("classpath:jedis-context.xml")
public class JedisRedisTemplateTest {
    @Resource
    RedisTemplate redisTemplate;
     @Test
    public void testOpsForValue() {   
        String redisKey1 = "jedis_redis_key_1";
        String originValue = "redis by jedis!";
        Jackson2JsonRedisSerializer<String> serializer = new Jackson2JsonRedisSerializer(String.class);
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.opsForValue().set(redisKey1, originValue);
        redisStoredValue = redisTemplate.opsForValue().get(redisKey1);
        assertEquals(redisStoredValue, originValue);
    }
}

LettuceRedisTemplateTest.java :使用lettuce客戶端

@RunWith(SpringJUnit4Cla***unner.class)
@ContextConfiguration("classpath:lettuce-context.xml")
public class LettuceRedisTemplateTest{
    @Resource
    RedisTemplate redisTemplate;
     @Test
    public void testOpsForValue() {   
        String redisKey1 = "lettuce_redis_key_1";
        String originValue = "redis by lettuce!";
        Jackson2JsonRedisSerializer<String> serializer = new Jackson2JsonRedisSerializer(String.class);
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.opsForValue().set(redisKey1, originValue);
        redisStoredValue = redisTemplate.opsForValue().get(redisKey1);
        assertEquals(redisStoredValue, originValue);
    }
}

對比兩個測試用例, 測試用例方法,基本一致,很清晰的感受到spring data redis框架帶來的擴展性。修改底層redis客戶端實現技術,而不會影響到上層現有方法(如redisTemplate方法)

運行2個用例結果

127.0.0.1:6379> keys *
1) "\"lettuce_redis_key_1\""
2) "\"jedis_redis_key_1\""
127.0.0.1:6379> get  "\"lettuce_redis_key_1\""
"\"redis by lettuce!\""
127.0.0.1:6379> get  "\"jedis_redis_key_1\""
"\"redis by jedis!\""

現在環境搭建完畢。

2.序列工具

從框架的角度來看,Redis中存儲的數據只是字節數。雖然Redis本身支持各種類型,但大多數情況下,這些指的是數據存儲的方式,而不是它所代表的格式。由用戶決定信息是否轉換爲字符串或任何其他對象。用戶(自定義)類型和原始數據(反之亦然)之間的轉換通過RedisSerializer接口(包org.springframework.data.redis.serializer)在Spring Data Redis中處理,顧名思義,它負責處理序列化過程。Spring data redis提供了多個序列化工具。

2.1 RedisSerializer API

//對象到字節數組(二進制數據)的基本接口序列化和反序列化
public interface RedisSerializer<T> {

   /**
    *將給定對象序列化爲二進制數據
    */
   byte[] serialize(T t) throws SerializationException;

   /**
    * 從給定的二進制數據反序列化對象。
    */
   T deserialize(byte[] bytes) throws SerializationException;
}

2.2 內置序列化實現

org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer

org.springframework.data.redis.serializer.GenericToStringSerializer

org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer

org.springframework.data.redis.serializer.JacksonJsonRedisSerializer

org.springframework.data.redis.serializer.JdkSerializationRedisSerializer

org.springframework.data.redis.serializer.OxmSerializer

org.springframework.data.redis.serializer.StringRedisSerializer

2.3 RedisSerializer使用場景

在RedisTemplate,RedisMessageListenerContainer,DefaultStringRedisConnection使用。

比如RedisTemplate。

public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V> {
...
/ **
* @return是否應使用默認的序列化程序。 如果沒有,任何序列化不明確集將會
*保持爲空,值將不會被序列化或反序列化。
* /
public boolean isEnableDefaultSerializer(){
    return enableDefaultSerializer;
}


/ **
* @param enableDefaultSerializer是否應使用默認的序列化程序。 如果沒有,任何serializer不
*展示集將保持爲空,值將不會被序列化或反序列化。
* /
public void setEnableDefaultSerializer(boolean enableDefaultSerializer){
    this.enableDefaultSerializer = enableDefaultSerializer;
}


/ **
*返回此模板使用的默認序列化程序。
*:
* @return模板默認序列化
* /
public RedisSerializer <?> getDefaultSerializer(){
    return defaultSerializer;
}


/ **
*設置要用於此模板的默認序列化程序。 所有序列化(期望
* @link #setStringSerializer(RedisSerializer))初始化爲此值,除非顯式設置。 默認爲
* @link JdkSerializationRedisSerializer。
*:
* @param serializer默認序列化程序使用
* /
public void setDefaultSerializer(RedisSerializer <?> serializer){
    this.defaultSerializer = serializer;
}


/ **
*設置此模板使用的密鑰序列化程序。 默認爲@link #getDefaultSerializer()。
*:
* @param serializer此模板使用的密鑰序列化程序。
* /
public void setKeySerializer(RedisSerializer <?> serializer){
    this.keySerializer = serializer;
}


/ **
*返回此模板使用的密鑰序列化程序。
*:
* @返回此模板使用的密鑰序列化程序。
* /
public RedisSerializer <?> getKeySerializer(){
    return keySerializer;
}


/ **
*設置此模板使用的值序列化程序。 默認爲@link #getDefaultSerializer()。
*:
* @param serializer此模板使用的值序列化程序。
* /
public void setValueSerializer(RedisSerializer <?> serializer){
    this.valueSerializer = serializer;
}


/ **
*返回此模板使用的值序列化程序。
*:
* @返回此模板使用的值序列化程序。
* /
public RedisSerializer <?> getValueSerializer(){
    return valueSerializer;
}
...
}

2.4  測試

上面的JedisRedisTemplateTest 使用的序列化工具Jackson2JsonRedisSerializer。

127.0.0.1:6379> keys *
1) "\"jedis_redis_key_1\""
127.0.0.1:6379> get "\"jedis_redis_key_1\""
"\"redis by jedis!\""

改用StringRedisSerializer,操作redis後效果

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
1) "jedis_redis_key_1"
127.0.0.1:6379> get jedis_redis_key_1
"redis by jedis!"

3.認識RedisConnectionFactory&RedisTemplate

wKiom1htEGjzneikAACAPOYPyvQ594.png

通過這個結構,可以實現客戶端工具的無縫切換。

RedisConnection
與Redis服務器的連接。 作爲各種Redis客戶端庫(或驅動程序)的通用抽象。


RedisConnectionFactory
線程安全的Redis連接工廠。
RedisTemplate
幫助類,簡化了Redis數據訪問模板代碼。






RedisTemplate模板提供了操作視圖(根據Redis命令引用進行分組),它提供豐富的,一般化的接口,用於對某種類型或某個鍵(通過KeyBound接口)進行處理,如下所述

操作視圖:Operational views

Interface

Description

Key Type Operations

ValueOperations

Redis string (or value) operations

ListOperations

Redis list operations

SetOperations

Redis set operations

ZSetOperations

Redis zset (or sorted set) operations

HashOperations

Redis hash operations

HyperLogLogOperations

Redis HyperLogLog operations like (pfadd, pfcount,…)

Key Bound Operations

BoundValueOperations

Redis string (or value) key bound operations

BoundListOperations

Redis list key bound operations

BoundSetOperations

Redis set key bound operations

BoundZSetOperations

Redis zset (or sorted set) key bound operations

BoundHashOperations

Redis hash key bound operations


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章