Spring Data Redis Example
August 01, 2018
This page will walk through Spring Data Redis example. Spring Data provides API to perform Redis operations with ease. Redis is an open source, in memory data-structure store that can be used as database, cache and message broker. Redis supports data-structure such as strings, hashes, lists, sets etc. Redis is a NoSQL storage and uses key/value to store data. Spring Data provides different connection factories to get Redis connections. The example of connection factories are JedisConnectionFactory
, LettuceConnectionFactory
etc. In our example we will use JedisConnectionFactory
. Jedis is a Java Redis client that is easy to use and small in size. Spring Data provides RedisTemplate
to perform Redis operations. RedisTemplate
has methods such as opsForList()
, opsForSet()
, opsForHash()
etc that return ListOperations
, SetOperations
, HashOperations
respectively. Most of the time we perform Redis operations with string datatype. So Spring Data has provided a string-focused extension as StringRedisTemplate
that extends RedisTemplate
. So StringRedisTemplate
has all methods of RedisTemplate
to perform Redis operations based on string datatype. In our example we will provide Spring Data and Redis configurations using JavaConfig as well as XML configurations with complete example.
Contents
Technologies Used
We are using following software in our example.1. Java 8
2. Spring 4.3
3. Spring Data Redis 1.8.7.RELEASE
4. Gradle 3.3
5. Maven 3.3
6. Eclipse Mars
Gradle and Maven
For Spring Data Redis JAR dependency we need to usespring-boot-starter-data-redis
. Find the Gradle and Maven file used in our example.
build.gradle
apply plugin: 'java' apply plugin: 'eclipse' archivesBaseName = 'Concretepage' version = '1.0-SNAPSHOT' repositories { mavenCentral() } dependencies { compile 'org.springframework.boot:spring-boot-starter:1.5.7.RELEASE' compile 'org.springframework.boot:spring-boot-starter-data-redis:1.5.7.RELEASE' }
<?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> <groupId>com.concretepage</groupId> <artifactId>spring-boot-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-demo</name> <description>Spring Boot Demo Project</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.7.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
RedisTemplate
RedisTemplate
is the central class to interact with the Redis data. It performs automatic serialization and deserialization between the given objects and binary data stored in Redis. By default RedisTemplate
uses Java serialization. This class is thread-safe once configured. RedisTemplate
can be instantiated using different connection factory such as JedisConnectionFactory
and LettuceConnectionFactory
.
1.
JedisConnectionFactory
uses JedisPoolConfig
for connection pooling.
2.
LettuceConnectionFactory
uses LettucePool
for connection pooling. To work with Lettuce connector we need to add extra JAR .
For Gradle
compile 'biz.paluch.redis:lettuce:5.0.0.Beta1'
<dependency> <groupId>biz.paluch.redis</groupId> <artifactId>lettuce</artifactId> <version>5.0.0.Beta1</version> </dependency>
JedisConnectionFactory
to instantiate RedisTemplate
. Jedis is a Java Redis client which is small in size and easy to use.
RedisTemplate
has different methods for data operations. Find some of them.
1.
ValueOperations<K,V> opsForValue()
opsForValue
returns ValueOperations
that performs operation on simple values.
2.
ListOperations<K,V> opsForList()
opsForList()
returns ListOperations
that performs operation on list values.
3.
SetOperations<K,V> opsForSet()
opsForSet()
returns SetOperations
that performs operation on set values.
4.
HashOperations<K,HK,HV> opsForHash()
opsForHash()
returns HashOperations
that performs operation on hash values.
If our most of the operation is string based then we can use
StringRedisTemplate
that is string-focused extension of RedisTemplate
.
Redis Java Configuration
Here we will configure Spring Data with Redis using JavaConfig.RedisConfig.java
package com.concretepage.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import com.concretepage.bean.Person; import redis.clients.jedis.JedisPoolConfig; @Configuration @ComponentScan("com.concretepage") public class RedisConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(5); poolConfig.setTestOnBorrow(true); poolConfig.setTestOnReturn(true); JedisConnectionFactory connectionFactory = new JedisConnectionFactory(poolConfig); connectionFactory.setUsePool(true); connectionFactory.setHostName("localhost"); connectionFactory.setPort(6379); return connectionFactory; } @Bean public RedisTemplate<String, Person> redisTemplate() { RedisTemplate<String, Person> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setEnableTransactionSupport(true); return redisTemplate; } @Bean public StringRedisTemplate stringRedisTemplate() { StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory()); stringRedisTemplate.setEnableTransactionSupport(true); return stringRedisTemplate; } }
JedisConnectionFactory
uses host name as localhost and port as 6379 by default. To change these values use setHostName()
and setPort()
respectively. To enable/disable using of connection pool, we need to pass Boolean values to setUsePool()
method.
RedisTemplate
does not provide transaction support by default. To enable it we need to call its method
setEnableTransactionSupport(true)
StringRedisTemplate
to enable transaction support.
We will create demo project using JavaConfig as well as XML configuration. Here find the demo project structure using JavaConfig.

Redis XML Configuration
Here we will provide XML configuration for Spring Data with Redis. We will configureJedisConnectionFactory
with connection pooling, RedisTemplate
and StringRedisTemplate
using XML configuration.
spring-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.concretepage" /> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" p:max-total="5" p:test-on-borrow="true" p:test-on-return="true"/> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="localhost" p:port="6379" p:use-pool="true"> <constructor-arg ref="jedisPoolConfig"/> </bean> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory" p:enable-transaction-support="true"/> <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory" p:enable-transaction-support="true"/> </beans>

@Transactional Support
When we create anyRedisTemplate
bean then by default they will not support Spring @Transactional
annotation. We need to enable it explicitly by calling setEnableTransactionSupport(true)
for each and every RedisTemplate
. We have also to enable transaction support for StringRedisTemplate
explicitly by calling
setEnableTransactionSupport(true)
@Bean public RedisTemplate<String, Person> redisTemplate() { RedisTemplate<String, Person> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setEnableTransactionSupport(true); return redisTemplate; }
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory" p:enable-transaction-support="true"/>
@Transactional
as following.
@Repository @Transactional public class FriendDAO { ------ }
ListOperations
It is used for Redis list specific operations. It is initialized as following.@Autowired private RedisTemplate<String, Person> redisTemplate; ListOperations<String, Person> listOps = redisTemplate.opsForList();
ListOperations
using javax.annotation.Resource
annotation as following.
@Resource(name="redisTemplate") ListOperations<String, Person> listOps;
RedisTemplate
bean configured in JavaConfig or XML Configuration. Now find some of ListOperations
methods.
leftPush(K key, V value): Prepends value to key.
rightPush(K key, V value): Appends value to key.
leftPop(K key): Removes and returns first element in list stored at key.
rightPop(K key): Removes and returns last element in list stored at key.
remove(K key, long count, Object value): Removes the first given number (count) of occurrences of value from the list stored at key.
index(K key, long index): Fetches element at index from list at key.
size(K key): Fetches the size of list stored at key.
Now find the example of
ListOperations
. Here we are performing create, read and delete operations.
FriendDAO.java
package com.concretepage.dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.concretepage.bean.Person; @Repository @Transactional public class FriendDAO { private static final String KEY = "friends"; @Autowired private RedisTemplate<String, Person> redisTemplate; public void addFriend(Person person) { redisTemplate.opsForList().leftPush(KEY, person); } public long getNumberOfFriends() { return redisTemplate.opsForList().size(KEY); } public Person getFriendAtIndex(Integer index) { return redisTemplate.opsForList().index(KEY, index); } public void removeFriend(Person p) { redisTemplate.opsForList().remove(KEY, 1, p); } }
package com.concretepage.bean; import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = 1L; private int id; private String name; private int age; public Person() { } public Person(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return id +" - " + name + " - " + age; } @Override public boolean equals(final Object obj) { if (obj == null) { return false; } final Person person = (Person) obj; if (this == person) { return true; } else { return (this.name.equals(person.name) && this.age == person.age); } } @Override public int hashCode() { int hashno = 7; hashno = 13 * hashno + (name == null ? 0 : name.hashCode()); return hashno; } }
FriendDAO.java
. Find the code snippet.
System.out.println("--Example of RedisTemplate for ListOperations--"); FriendDAO friendDAO = context.getBean(FriendDAO.class); Person p1 = new Person(1, "Mahesh", 30); friendDAO.addFriend(p1); Person p2 = new Person(2, "Krishna", 35); friendDAO.addFriend(p2); System.out.println("Number of friends: " + friendDAO.getNumberOfFriends()); System.out.println(friendDAO.getFriendAtIndex(1)); friendDAO.removeFriend(p2); System.out.println(friendDAO.getFriendAtIndex(1)); //It will return null, because value is deleted.
--Example of RedisTemplate for ListOperations-- Number of friends: 2 1 - Mahesh - 30 null
SetOperations
SetOperations
performs Redis set specific operations. Find some of its methods.
add(K key, V... values): Adds values to set at key.
members(K key): Fetches all elements of set at key.
size(K key): Fetches size of set at key.
remove(K key, Object... values): Removes given values from set at key and returns the number of removed elements.
Now find the example of
SetOperations
. Here we will perform create, read and delete operations.
FamilyDAO.java
package com.concretepage.dao; import java.util.Set; import javax.annotation.Resource; import org.springframework.data.redis.core.SetOperations; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.concretepage.bean.Person; @Repository @Transactional public class FamilyDAO { private static final String KEY = "myfamily"; @Resource(name="redisTemplate") private SetOperations<String, Person> setOps; public void addFamilyMembers(Person... persons) { setOps.add(KEY, persons); } public Set<Person> getFamilyMembers() { return setOps.members(KEY); } public long getNumberOfFamilyMembers() { return setOps.size(KEY); } public long removeFamilyMembers(Person... persons) { return setOps.remove(KEY, (Object[])persons); } }
System.out.println("--Example of SetOperations--"); FamilyDAO familyDAO = context.getBean(FamilyDAO.class); Person p11 = new Person(101, "Ram", 30); Person p12 = new Person(102, "Lakshman", 25); Person p13 = new Person(103, "Bharat", 35); familyDAO.addFamilyMembers(p11, p12, p13); System.out.println("Number of Family members: " + familyDAO.getNumberOfFamilyMembers()); System.out.println(familyDAO.getFamilyMembers()); System.out.println("No. of Removed Family Members: " + familyDAO.removeFamilyMembers(p11, p12)); System.out.println(familyDAO.getFamilyMembers());
--Example of SetOperations-- Number of Family members: 3 [101 - Ram - 30, 103 - Bharat - 35, 102 - Lakshman - 25] No. of Removed Family Members: 2 [103 - Bharat - 35]
HashOperations
HashOperations
performs Redis map specific operations working on a hash. Find some of its methods.
putIfAbsent(H key, HK hashKey, HV value): Sets the value of a hash
hashKey
only if hashKey does not exist.
put(H key, HK hashKey, HV value): Sets the value of a hash
hashKey
.
get(H key, Object hashKey): Fetches value for given
hashKey
from hash at key.
size(H key): Fetches size of hash at key.
entries(H key): Fetches entire hash stored at key.
delete(H key, Object... hashKeys): Deletes given hash
hashKeys
at key.
Find the example of
HashOperations
with create, read, update and delete (CRUD) operations.
EmployeeDAO.java
package com.concretepage.dao; import java.util.Map; import javax.annotation.Resource; import org.springframework.data.redis.core.HashOperations; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.concretepage.bean.Person; @Repository @Transactional public class EmployeeDAO { private static final String KEY = "employees"; @Resource(name="redisTemplate") private HashOperations<String, Integer, Person> hashOps; public void addEmployee(Person person) { hashOps.putIfAbsent(KEY, person.getId(), person); } public void updateEmployee(Person person) { hashOps.put(KEY, person.getId(), person); } public Person getEmployee(Integer id) { return hashOps.get(KEY, id); } public long getNumberOfEmployees() { return hashOps.size(KEY); } public Map<Integer, Person> getAllEmployees() { return hashOps.entries(KEY); } public long deleteEmployees(Integer... ids) { return hashOps.delete(KEY, (Object)ids); } }
System.out.println("--Example of HashOperations--"); EmployeeDAO empDAO = context.getBean(EmployeeDAO.class); Person emp1 = new Person(11, "Ravan", 45); Person emp2 = new Person(12, "Kumbhkarn", 35); Person emp3 = new Person(13, "Vibhisan", 25); empDAO.addEmployee(emp1); empDAO.addEmployee(emp2); empDAO.addEmployee(emp3); System.out.println("No. of Employees: "+ empDAO.getNumberOfEmployees()); System.out.println(empDAO.getAllEmployees()); emp2.setAge(20); empDAO.updateEmployee(emp2); System.out.println(empDAO.getEmployee(12));
--Example of HashOperations-- No. of Employees: 3 {13=13 - Vibhisan - 25, 11=11 - Ravan - 45, 12=12 - Kumbhkarn - 35} 12 - Kumbhkarn - 20
StringRedisTemplate
StringRedisTemplate
is the string-focused extension of RedisTemplate
. Most of the time we perform Redis operations with string and hence Spring Data provides a dedicated template i.e. StringRedisTemplate
. Here we will discuss opsForValue()
method of StringRedisTemplate
that will return ValueOperations
.
@Autowired private StringRedisTemplate stringRedisTemplate; ValueOperations<String, String> valueOps = StringRedisTemplate.opsForValue();
ValueOperations
methods.
setIfAbsent(K key, V value): Sets key to hold the string value if key is absent.
set(K key, V value): Sets value for key.
get(Object key): Fetches the value of key.
Now find the example of CRUD operations using
StringRedisTemplate
.
UserDAO.java
package com.concretepage.dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @Repository @Transactional public class UserDAO { private static final String KEY = "user"; @Autowired private StringRedisTemplate stringRedisTemplate; public void addUserName(String uname) { stringRedisTemplate.opsForValue().setIfAbsent(KEY, uname); } public void updateUserName(String uname) { stringRedisTemplate.opsForValue().set(KEY, uname); } public String getUserName() { return stringRedisTemplate.opsForValue().get(KEY); } public void deleteUser() { stringRedisTemplate.delete(KEY); } }
System.out.println("--Example of StringRedisTemplate--"); UserDAO userDAO = context.getBean(UserDAO.class); userDAO.addUserName("sriram"); System.out.println(userDAO.getUserName()); userDAO.updateUserName("srikrishna"); System.out.println(userDAO.getUserName()); userDAO.deleteUser(); System.out.println(userDAO.getUserName()); //It will return null, because value is deleted.
--Example of StringRedisTemplate-- sriram srikrishna null
Main Class to Run Application
Find the Main class used in our demo with JavaConfig to test Redis operations.Main.java
package com.concretepage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.concretepage.bean.Person; import com.concretepage.config.RedisConfig; import com.concretepage.dao.EmployeeDAO; import com.concretepage.dao.FamilyDAO; import com.concretepage.dao.FriendDAO; import com.concretepage.dao.UserDAO; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(RedisConfig.class); context.refresh(); System.out.println("--Example of RedisTemplate for ListOperations--"); FriendDAO friendDAO = context.getBean(FriendDAO.class); Person p1 = new Person(1, "Mahesh", 30); friendDAO.addFriend(p1); Person p2 = new Person(2, "Krishna", 35); friendDAO.addFriend(p2); System.out.println("Number of friends: " + friendDAO.getNumberOfFriends()); System.out.println(friendDAO.getFriendAtIndex(1)); friendDAO.removeFriend(p2); System.out.println(friendDAO.getFriendAtIndex(1)); //It will return null, because value is deleted. System.out.println("--Example of SetOperations--"); FamilyDAO familyDAO = context.getBean(FamilyDAO.class); Person p11 = new Person(101, "Ram", 30); Person p12 = new Person(102, "Lakshman", 25); Person p13 = new Person(103, "Bharat", 35); familyDAO.addFamilyMembers(p11, p12, p13); System.out.println("Number of Family members: " + familyDAO.getNumberOfFamilyMembers()); System.out.println(familyDAO.getFamilyMembers()); System.out.println("No. of Removed Family Members: " + familyDAO.removeFamilyMembers(p11, p12)); System.out.println(familyDAO.getFamilyMembers()); System.out.println("--Example of HashOperations--"); EmployeeDAO empDAO = context.getBean(EmployeeDAO.class); Person emp1 = new Person(11, "Ravan", 45); Person emp2 = new Person(12, "Kumbhkarn", 35); Person emp3 = new Person(13, "Vibhisan", 25); empDAO.addEmployee(emp1); empDAO.addEmployee(emp2); empDAO.addEmployee(emp3); System.out.println("No. of Employees: "+ empDAO.getNumberOfEmployees()); System.out.println(empDAO.getAllEmployees()); emp2.setAge(20); empDAO.updateEmployee(emp2); System.out.println(empDAO.getEmployee(12)); System.out.println("--Example of StringRedisTemplate--"); UserDAO userDAO = context.getBean(UserDAO.class); userDAO.addUserName("sriram"); System.out.println(userDAO.getUserName()); userDAO.updateUserName("srikrishna"); System.out.println(userDAO.getUserName()); userDAO.deleteUser(); System.out.println(userDAO.getUserName()); //It will return null, because value is deleted. } }
Test Application
To test our Spring Data and Redis demo application, find the steps given below.1. Install and start Redis using the link.
2. If you are using Windows OS, you can install Cygwin first and then install Redis in it.
3. Redis will start on localhost at port 6379.
4. Now download source and run
Main.java
as Java Application.