1. Overview

This tutorial is an introduction to Spring Data Redis, which provides the abstractions of the Spring Data platform to Redis — the popular in-memory data structure store.

Redis is driven by a keystore-based data structure to persist data and can be used as a database, cache, message broker, etc.

We’ll be able to use the common patterns of Spring Data (templates, etc.) while also having the traditional simplicity of all Spring Data projects.

2. Maven Dependencies

Let’s start by declaring the Spring Data Redis dependencies in the pom.xml:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>3.2.0</version>
 </dependency>

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>5.1.2</version>
    <type>jar</type>
</dependency>

The latest versions of spring-data-redis and jedis can be downloaded from Maven Central.

Alternatively, we can use the Spring Boot starter for Redis, which will eliminate the need for separate spring-data and jedis dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>3.2.0</version>
</dependency>

Again, Maven Central offers the latest version information.

3. The Redis Configuration

To define the connection settings between the application client and the Redis server instance, we need to use a Redis client.

There is a number of Redis client implementations available for Java. In this tutorial, we’ll use Jedis — a simple and powerful Redis client implementation.

There is good support for both XML and Java configuration in the framework. For this tutorial, we’ll use Java-based configuration.

3.1. Java Configuration

Let’s start with the configuration bean definitions:

@Bean
JedisConnectionFactory jedisConnectionFactory() {
    return new JedisConnectionFactory();
}

@Bean
public RedisTemplate<String, Object> redisTemplate() {
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(jedisConnectionFactory());
    return template;
}

The configuration is quite simple.

First, using the Jedis client, we’re defining a connectionFactory.

Then we defined a RedisTemplate using the jedisConnectionFactory. This can be used for querying data with a custom repository.

3.2. Custom Connection Properties

Notice that the usual connection-related properties are missing in the above configuration. For example, the server address and port are missing in the configuration. The reason is simple: we’re using the defaults.

However, if we need to configure the connection details, we can always modify the jedisConnectionFactory configuration:

@Bean
JedisConnectionFactory jedisConnectionFactory() {
    JedisConnectionFactory jedisConFactory
      = new JedisConnectionFactory();
    jedisConFactory.setHostName("localhost");
    jedisConFactory.setPort(6379);
    return jedisConFactory;
}

4. Redis Repository

Let’s use a Student entity:

@RedisHash("Student")
public class Student implements Serializable {
  
    public enum Gender { 
        MALE, FEMALE
    }

    private String id;
    private String name;
    private Gender gender;
    private int grade;
    // ...
}

4.1. The Spring Data Repository

Let’s now create the StudentRepository:

@Repository
public interface StudentRepository extends CrudRepository<Student, String> {}

5. Data Access Using StudentRepository

By extending CrudRepository in StudentRepository, we automatically get a complete set of persistence methods that perform CRUD functionality.

5.1. Saving a New Student Object

Let’s save a new student object in the data store:

Student student = new Student(
  "Eng2015001", "John Doe", Student.Gender.MALE, 1);
studentRepository.save(student);

5.2. Retrieving an Existing Student Object

We can verify the correct insertion of the student in the previous section by fetching the student data:

Student retrievedStudent = 
  studentRepository.findById("Eng2015001").get();

5.3. Updating an Existing Student Object

Let’s change the name of the student retrieved above and save it again:

retrievedStudent.setName("Richard Watson");
studentRepository.save(student);

Finally, we can retrieve the student’s data again and verify that the name is updated in the data store.

5.4. Deleting Existing Student Data

We can delete the inserted student data:

studentRepository.deleteById(student.getId());

Now we can search for the student object and verify that the result is null.

5.5. Find All Student Data

We can insert a few student objects:

Student engStudent = new Student(
  "Eng2015001", "John Doe", Student.Gender.MALE, 1);
Student medStudent = new Student(
  "Med2015001", "Gareth Houston", Student.Gender.MALE, 2);
studentRepository.save(engStudent);
studentRepository.save(medStudent);

We can also achieve this by inserting a collection. For that, there is a different method — saveAll() — that accepts a single Iterable object containing multiple student objects that we want to persist.

To find all inserted students, we can use the findAll() method:

List<Student> students = new ArrayList<>();
studentRepository.findAll().forEach(students::add);

Then we can quickly check the size of the students list or verify for a greater granularity by checking the properties of each object.

6. Conclusion

In this article, we went through the basics of Spring Data Redis.

The source code of the examples above can be found in the GitHub project.