How to Use Redis in Java

Redis has several Java clients, but three are officially recommended: Jedis, Lettuce, and Redisson. The Spring framework provides integration with these clients through Spring Data Redis, and Spring Boot further simplifies the process with the spring-boot-starter-data-redis dependency.

Using Jedis Client

Step 1: Add Jedis Dependency
To start, create a Maven project and add the following dependency:

1
2
3
4
5
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>

Step 2: Basic Jedis Operations

Using Jedis is similar to working with JDBC. Below is a simple example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Test
public void testRedis() {
// 1. Establish connection
Jedis jedis = new Jedis("localhost", 6379);

// 2. Perform operations
jedis.set("username", "ganyu");
String username = jedis.get("username");

jedis.hset("myhash", "addr", "shenzhen");
String hvalue = jedis.hget("myhash", "addr");

// Retrieve all keys
Set<String> keys = jedis.keys("*");
for (String key : keys) {
System.out.println(key);
}

// 3. Close connection
jedis.close();
}

Using Spring Data Redis

Introduction

Spring Data Redis provides a highly abstracted class, RedisTemplate, which categorizes various Redis operations into interfaces like:

  • ValueOperations: Key-value operations
  • SetOperations: Set-type data
  • ZSetOperations: Sorted set data
  • HashOperations: Hash data
  • ListOperations: List data

Step 1: Add Maven Dependency

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Step 2: Configure application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: spring_data_redis_demo
redis:
host: localhost
port: 6379
# password: 123456 # Set the password if your Redis server has one
database: 0 # Redis provides 16 databases by default. The default is DB 0.
jedis:
pool:
max-active: 8 # Maximum connections
max-wait: 1ms # Maximum wait time for connections
max-idle: 4 # Maximum idle connections
min-idle: 0 # Minimum idle connections

Step 3: Using RedisTemplate for Operations

First, inject RedisTemplate into your class:

1
2
@Autowired
private RedisTemplate redisTemplate;

Example for string operations:

1
2
3
4
5
6
7
8
@Test
public void testString() {
ValueOperations valueOperations = redisTemplate.opsForValue();
valueOperations.set("city", "sz");

String city = (String) valueOperations.get("city");
System.out.println(city);
}

Serialization Issue in RedisTemplate

By default, RedisTemplate uses JdkSerializationRedisSerializer, which may cause key-value pairs to be unreadable from Redis CLI. There are two solutions:

Solution 1: Custom Serializer

Create a RedisConfig class in config package to change the serializer.

RedisConfig:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
   @Configuration
public class RedisConfig extends CachingConfigurerSupport{
@Bean
public RedisTemplate<Object, Object> redisTemplate (RedisConnectionFactory connectionFactory{
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
//default KeySerializer:JdkSerializationRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());

redisTemplate.setConnectionFactory(connectionFactory);

return redisTemplate;
}
}

Solution 2: Use StringRedisTemplate

Alternatively, you can use StringRedisTemplate to avoid creating a custom config.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
SpringDataRedis provides a highly abstracted class, which encapsulates a large number of Jedis APIs.
*/
@Autowired
//private RedisTemplate redisTemplate;
//If you use RedisTemplate, you need to create a RedisConfig configuration class to change the serialization method of RedisTemplate. Otherwise, the key will be unreadable in the Redis client.
private StringRedisTemplate stringRedisTemplate; //Using StringRedisTemplate eliminates the need to write a configuration class and ensures the key is readable in the Redis client.

@Test
public void testString(){
ValueOperations valueOperations = stringRedisTemplate.opsForValue();
// Set the key-value pair
valueOperations.set("city", "sz");
}

Common Redis Operations Using RedisTemplate

First, you need to inject an instance of RedisTemplate

1
2
@Autowired
private RedisTemplate redisTemplate;
  1. String Operations

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    @Test
    public void testString() {
    ValueOperations valueOperations = stringRedisTemplate.opsForValue();

    // Setting a key-value pair
    valueOperations.set("city", "sz");

    // Retrieving the value of the key
    String city = (String) valueOperations.get("city");
    System.out.println(city);

    // Setting a key with expiration time
    valueOperations.set("key1", "value1", 10L, TimeUnit.SECONDS);

    // Using SETNX (Set if Not Exist)
    Boolean result1 = valueOperations.setIfAbsent("city", "nanjing");
    System.out.println(result1);
    }
  2. Hash Operations

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    @org.junit.jupiter.api.Test
    public void testHash(){
    HashOperations hashOperations = redisTemplate.opsForHash();
    // Adding values to a hash
    hashOperations.put("hobbies", "hobby1", "piano");
    hashOperations.put("hobbies", "hobby2", "jogging");

    // Retrieving a specific field value
    String hobby1 = (String) hashOperations.get("hobbies", "hobby1");
    System.out.println(hobby1);

    // Retrieving all fields from a hash
    Set keys = hashOperations.keys("hobbies"); // Returns all fields with key-value pairs whose key is hobbies, in this case hobby1, hobby2
    for (Object key : keys) {
    System.out.println(key);
    }

    // Retrieving all values from a hash
    List values = hashOperations.values("hobbies");
    for (Object value : values) {
    System.out.println(value);
    }
    }
  3. List Operations

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    @Test
    public void testList(){
    ListOperations listOperations = redisTemplate.opsForList();

    // Adding values to a list
    listOperations.leftPush("mylist", "a"); // single value
    listOperations.leftPushAll("mylist", "b", "c", "d"); // multiple values
    // Retrieving values from a list
    // Gets the elements in the specified range of the list, from start to stop. The last element can also be indexed as -1.
    List<String> mylist = listOperations.range("mylist", 0, -1);
    for (String item : mylist) {
    System.out.println(item);
    }

    // Getting the length of a list
    Long sizeLong = listOperations.size("mylist");
    int sizeInt = sizeLong.intValue();// Long->int
    for (int i = 0; i < sizeInt; i++) { // for循环中i必须是int
    // Removing and retrieving the last element from the list
    String mykey = (String) listOperations.rightPop("mylist");
    System.out.println(mykey);
    }
    }
  4. Set Operations

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @Test
    public void testSet(){
    SetOperations setOperations = redisTemplate.opsForSet();
    // Adding values to a set
    setOperations.add("myset", "a","b","c","a");

    // Retrieving all members of a set
    Set<String> myset = setOperations.members("myset");
    for (String item : myset) {
    System.out.print(" " + item);
    }

    // Removing members from a set
    setOperations.remove("myset", "b");

    // Retrieving all members of a set again
    myset = setOperations.members("myset");
    for (String item : myset) {
    System.out.print(" " + item);
    }
    }
  5. Sorted Set Operations

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    @Test
    public void testZSet(){
    ZSetOperations zSetOperations = redisTemplate.opsForZSet();

    // Adding values to a sorted set
    zSetOperations.add("myZSet", "a", 10.0);
    zSetOperations.add("myZSet", "b", 11.0);
    zSetOperations.add("myZSet", "c", 12.0);
    zSetOperations.add("myZSet", "a", 13.0);

    // Retrieving values from a sorted set
    Set<String> myZSet = zSetOperations.range("myZSet", 0, -1);
    for (String item : myZSet) {
    System.out.println(item);
    }

    // Incrementing the score of a member
    zSetOperations.incrementScore("myZSet", "c", 30.0);

    // Viewing the updated sorted set
    myZSet = zSetOperations.range("myZSet", 0, -1);
    for (String item : myZSet) {
    System.out.println(item);
    }

    // Removing members from a sorted set
    zSetOperations.remove("myZSet", "b", "a");

    // Viewing the updated sorted set again
    myZSet = zSetOperations.range("myZSet", 0, -1);
    for (String item : myZSet) {
    System.out.println(item);
    }
    }
  6. Common Commands

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Test
    public void testCommon(){
    // Retrieving all keys
    Set<String> keys = redisTemplate.keys("*");
    for (String key : keys) {
    System.out.println(key);
    }

    // Checking if a key exists
    Boolean hasKey = redisTemplate.hasKey("myset");
    System.out.println(hasKey);

    // Deleting a key
    redisTemplate.delete("age");

    // Retrieving the type of a key
    DataType dataType = redisTemplate.type("myZSet");
    System.out.println(dataType);
    }