Spring Data Redis

Spring Data open source the Spring Data Redis project to facilitate Spring Boot operations, which encapsulates RedisTemplate and StringRedisTemplate.

In Spring Boot 1.x, the Spring Data Redis base layer uses Jedis to operate Redis, and after Spring Boot 2.0, the Spring Data Redis base layer uses the user interface Redis.

StringRedisTemplate is a subclass of RedisTemplate. The methods of the two classes are basically the same, and the differences are mainly reflected in the different data types of operation.

Both of the generics in the RedisTemplate are Object, meaning that the stored Key and Value can be an Object; Both generics of StringRedisTemplate are strings, meaning that the Key and Value of a StringRedisTemplate must be strings.

If you know that both the Key and the Value are strings, use StringRedisTemplate; If you know there is an Object in the Key and Value, use the RedisTemplate.

In previous studies, we learned that Redis itself is a key-value database, where keys and values can only store strings. For example, String is usually represented as “key”=”value”. The List type is “key”=[“value1”, “value2”, “value3”]. But when Java integrates Redis, we know that everything in Java is an object, so how does Redis treat objects in Java as keys or values?

Spring Data Redis provides a variety of automatic serialization and automatic deserialization, you can automatically convert Java objects into strings stored in Redis, you can also automatically convert strings stored in Redis into Java objects and apply them in Spring Boot.

An important prerequisite for automatic serialization and deserialization is that the class of an object must implement the serialization interface.

Environment set up

  1. Pom.xml introduces dependencies

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    Copy the code
  2. Application. Yml configuration

    spring:
      # Redis configuration
      redis:
        host: localhost
        port: 6379
        Use library 0
        database: 0
        Redis connection pool
        lettuce:
          pool:
            The default maximum number of connections in the pool is 8
            max-active: 8
            The maximum connection pool blocking time (using negative values to indicate no limit) defaults to -1
            max-wait: - 1
            The default maximum number of free connections in the connection pool is 8
            max-idle: 8
            The default minimum number of free connections in the connection pool is 8
            min-idle: 0
    Copy the code
  3. Into the template

    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    Copy the code

Operation Key related apis

1. The delete Key

Boolean result = stringRedisTemplate.delete("key");
Copy the code

2. Check whether the Key exists

Boolean result = stringRedisTemplate.hasKey("key");
Copy the code

3. Check the Key type

DataType type = stringRedisTemplate.type("key");
Copy the code

4. Obtain all keys

Set<String> keys = stringRedisTemplate.keys("*");
Copy the code

5. Check the Key expiration time

Long expire = stringRedisTemplate.getExpire("key");
Copy the code

Returns -1 if the Key is permanently stored, and -2 if the Key does not exist.

6. Obtain keys randomly

String randomKey = stringRedisTemplate.randomKey();
Copy the code

7. The Key name

stringRedisTemplate.rename("oldKey"."newKey");
Copy the code

NewKey must not exist. If it does not exist, change it. If it does exist, an error is reported.

You can also use the following API, which determines whether newKey does not exist before changing oldKey and returns true if it does, or false if it does.

Boolean reuslt = stringRedisTemplate.renameIfAbsent("oldKey"."newKey");
Copy the code

8. Move the Key

Boolean result = stringRedisTemplate.move("key".1);
Copy the code

The second parameter is dbIndex, which indicates the library number.

StringRedisTemplate and RedisTemplate

1. The relationship between

StringRedisTemplate is a subclass of RedisTemplate.

2. The difference between

  • StringRedisTemplate uses a different serialization strategy for its Key Value. By default, StringRedisSerializer is used for StringRedisTemplate. RedisTemplate USES the JDK serialization strategy (JdkSerializationRedisSerializer) by default.
    • The String serialization strategy serializes key-value into a plaintext String, which is stored as “name” in Redis.
    • The JDK serialization strategy serializes key-values into byte arrays, which are stored in Redis as “\xAD\xED\x00”.
  • The StringRedisTemplate can only manage data in a StringRedisTemplate, and a RedisTemplate can only manage data in a RedisTemplate. Because StringRedisTemplate can’t handle data stored as a byte array, RedisTemplate can’t handle data stored as a string in plain text (so data stored with StringRedisTemplate doesn’t need to be fetched with RedisTemplate, And vice versa).
  • The Key and Value of a StringRedisTemplate must both be strings (generics are

    ), and the Key and Value of a RedisTemplate must both be Object (generics are
    , Custom objects must implement the serialization interface.,>
    ,>

3. Select

If the data to be accessed in Redis is String data, use StringRedisTemplate.

If the data to be accessed in Redis is complex object type data, and you want to retrieve an object directly from Redis without any data conversion, then using RedisTemplate is a better choice.

RedisTempate serialization

RedisTemplate uses JDK serialization by default.

The serialization rule is that no matter what type of Object your key-value is, such as String, List, Map, or custom Bean, if stored using RedisTemplate, it will be serialized as a byte array. It doesn’t matter if the Value is serialized as a byte array, but if the Key is serialized as a byte array, then the Redis client can’t fetch the Value from the Key. Because you need to provide a byte array of serialized keys to get the corresponding Value, if you want to get the Value, you can only get it through Java, which is actually very inconvenient.

In common scenarios, only values need to be stored as objects, and keys need to be strings. If we want Value to be Object, we need to use RedisTemplate, but the default serialization scheme for RedisTemplate is that both the Key and the Value are serialized by the JDK. For convenience, we want the Value to be Object and the Key not to be serialized. Therefore, when using RedisTemplate, we will manually change the default serialization scheme for the Key in RedisTemplate to String serialization. The default serialization scheme for Value remains JDK serialization.

One particular point to note is: In the RedisTemplate Hash data type, the default field serialization scheme for the Hash is also JDK serialization, so if we use the RedisTemplate Hash data type, we need to manually change the default field serialization scheme for the Hash to String serialization.

All serialization schemes in Redis (to name a few common ones) :

OpsFor method

The opsFor method is the pre-method of the API wrapped by Spring Data Redis. Whether it is RedisTemplate or StringRedisTemplate, any API that manipulates Data needs to call the opsFor method first to select the type to organize and manipulate the Data.

  • OpsForValue: The data structure type for organizing and manipulating data is String.
  • OpsForList: Data structures of type List to organize and manipulate data.
  • OpsForSet: The data structure type for organizing and manipulating data is Set.
  • OpsForZSet: The data structure type for organizing and manipulating data is ZSet.
  • OpsForHash: The data structure used to organize and manipulate data is of the Hash type.

For example, opsForValue provides apis that fundamentally organize and process data according to the String type in Redis, and opsForList provides apis that fundamentally organize and process data according to the List type in Redis. But the opsFor method that you call on StringRedisTemplate organizes and processes all the data that’s String; The opsFor method called by RedisTemplate organizes and processes data that is Object (including String). The former String is a data organization type in Redis, and the latter String is a data type in Java.

StringRedisTemplate related API

1. The String operation

API instructions The sample
set Set a pair of key-values stringRedisTemplate.opsForValue().set(“key”, “value”);
set Set a pair of key-values (set expiration time) stringRedisTemplate.opsForValue().set(“key”, “value””, 60, TimeUnit.SECONDS);
get Get the Value stringRedisTemplate.opsForValue().get(“key”);
append Additional Value stringRedisTemplate.opsForValue().append(“key”, “value”);

2. Operating the List

API instructions The sample
leftPush Put Value into List (left to right), create List if Key does not exist stringRedisTemplate.opsForList().leftPush(“key”, “value”);
leftPushAll Put several values into a List (from left to right), create a List if the Key does not exist stringRedisTemplate.opsForList().leftPushAll(“key”, “value1”, “value2”);
range Retrieve Value from partial List by subscript (Value subscript 0) stringRedisTemplate.opsForList().range(“key”, 0, -1);
index Get Value by subscript stringRedisTemplate.opsForList().index(“key”, 0);
leftPop Get the List header Value and remove the List header Value stringRedisTemplate.opsForList().leftPop(“key”);
rightPop Get the Value at the end of the List and remove the Value at the end of the List stringRedisTemplate.opsForList().rightPop(“key”);
trim By using the subscript of the List, only certain values are retained and all other values are deleted stringRedisTemplate.opsForList().trim(“key”, 1, 3);

3. The Set operation

API instructions The sample
add Put several values into a Set (duplicate values overwrite), and create a Set if the Key does not exist stringRedisTemplate.opsForSet().add(“key”, “value1”, “value2”);
members View all values in the Set stringRedisTemplate.opsForSet().members(“key”);
move Move a Value from one Set to another stringRedisTemplate.opsForSet().move(“key1”, “value”, “key2”);
pop Returns a random Set of values and removes them stringRedisTemplate.opsForSet().pop(“key”);
size Returns the number of values in a Set stringRedisTemplate.opsForSet().size(“key”);

4. Operating ZSet

API instructions The sample
add Put several values and their scores into a ZSet (duplicates are overwritten), and create a ZSet if the Key does not exist stringRedisTemplate.opsForZSet().add(“key”, “value”, 1);
range Through the subscript of ZSet, the Value of part of ZSet is obtained in ascending order (the Value with the lowest score is 0), and the score can be displayed stringRedisTemplate.opsForZSet().range(“key”, 0, 3);
rangeByScoreWithScores Through the score of ZSet, the Value of part of ZSet can be obtained in ascending order, and the score can be displayed stringRedisTemplate.opsForZSet().rangeByScoreWithScores(“key”, 0, 100);

5. The Hash operation

API instructions The sample
put Add a pair of field-values to the Hash, creating the Hash if the Key does not exist (overwriting the Field if it does exist) stringRedisTemplate.opsForHash().put(“key”, “field”, “value”);
get Gets a Value from the Hash stringRedisTemplate.opsForHash().get(“key”, “field”);
keys View all fields in the Hash stringRedisTemplate.opsForHash().keys(“key”);
values View all values in the Hash stringRedisTemplate.opsForHash().values(“key”);
putAll Add pairs of field-values to the Hash (overwrite if the Field exists) stringRedisTemplate.opsForHash().putAll(“key”, new HashMap<String, String>());
multiGet View several values through Field stringRedisTemplate.opsForHash().multiGet(“key”, Arrays.asList(“field1”, “field2”));

RedisTemplate related API

The API wrapped by RedisTemplate is the same as that wrapped by StringRedisTemplate, except that the Value type is different.

bound API

Spring Data Redis provides a bound API for StringRedisTemplate and RedisTemplate to make it easier to manipulate the Value of the same Key multiple times.

The bound API for StringRedisTemplate is used to demonstrate this.

Without using the Bound API:

stringRedisTemplate.opsForValue().set("key"."value");
stringRedisTemplate.opsForValue().append("key"." is a value");
String key = stringRedisTemplate.opsForValue().get("key");
Copy the code

Using the Bound API:

BoundValueOperations<String, String> keyValueOps = stringRedisTemplate.boundValueOps("key");
keyValueOps.set("value");
keyValueOps.append(" is a value");
String key = keyValueOps.get();
Copy the code