Redis is an in-memory key/value store. It is used as a database, cache and message broker. In this article, we will see some examples of Spring Data Redis. Before we get to start with the examples, we need to first install Redis and configure the server.
1. Overview of Redis
Redis is an extremely high-performance, lightweight key/value based data store. It provides several operations like persistenting byte arrays, lists, sets, and hash data structures. It also supports a way to generate atomic counters and also has an efficient topic-based pub/sub messaging functionality. It lacks in complex querying functionality. Redis servers can also be clustered together to povide distributed environment. One can interact with Redis using command line.
2. Installing Redis
- Download Redis Release. We have downloaded the release for Windows 3.0 on 64 bit.
- Download the binaries, bundled as zip file and the installer MSI file.
- Unzip the binaries to a new directory, for example,
c:\redis
. Copy the installer to the same directory. - Run the installer file and follow through the wizard.
- Once installed, redis is available as service. By default it will already be started.
3. Start Redis Manually
In case you want to start redis manually. Stop the redis service, go to the installed redis directory and run redis-server.exe
from command line.
C:\redis<redis-server.exe [5784] 06 Jan 08:46:59.903 # Warning: no config file specified, using the defaul t config. In order to specify a config file use redis-server.exe /path/to/redis. conf _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.0.500 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 5784 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' [5784] 06 Jan 08:46:59.920 # Server started, Redis version 3.0.500 [5784] 06 Jan 08:46:59.921 * The server is now ready to accept connections on po rt 6379
4. Accessing Redis using command line
Now that we have started the server, its good time to quickly test redis. Maybe insert a key/value and retrieve it.
In order to quickly test, you can use Redis command-line shell that you can use interactively.
- Go to the installed redis directory and then run
redis-cli
from command line.C:\redis<redis-cli 127.0.0.1:6379<
- Get all the keys.
127.0.0.1:6379< keys * (empty list or set) 127.0.0.1:6379>
- Insert a key value.
127.0.0.1:6379< set example spring-redis OK
- Get all the keys.
127.0.0.1:6379< keys * 1) "example" 127.0.0.1:6379>
- Let’s now get value of “example”.
127.0.0.1:6379< get example "spring-redis"
5. Accessing Redis using Java
In order to connect to Redis using java, you need to first download a redis driver. You can see the redis java drives listed here. In our examples, we will use Jedis.
Add the following dependency to your pom.xml
.
pom.xml:
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency>
6. Dependencies
Since we want to use spring support for accessing redis, you also need to add spring based artifacts to pom.xml
.
Here is the complete pom.xml
.
spring-data-redis
is for the spring-redis support.spring-core
andspring-context
for spring bean and context support.commons-pool2
– Apache commons pooljedis
– Redis Java Driver
pom.xml:
<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.javacodegeeks.spring.redis</groupId> <artifactId>springQuartzScheduler</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.5.0.RELEASE</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency> </dependencies> </project>
7. Spring Redis Configuration
To connect to Redis using Jedis, you need to create an instance of org.springframework.data.redis.connection.jedis.JedisConnectionFactory
.
The other driver libraries have corresponding ConnectionFactory
subclasses.
SpringRedisConfig:
package com.javacodegeeks.spring.redis; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.StringRedisTemplate; @Configuration public class SpringRedisConfig { @Bean public JedisConnectionFactory connectionFactory() { JedisConnectionFactory connectionFactory = new JedisConnectionFactory(); connectionFactory.setHostName("localhost"); connectionFactory.setPort(6379); return connectionFactory; } }
8. RedisTemplate Example
Just the way spring provides template classes, even for redis, spring provides RedisTemplate
to simplify Redis data access code.
SpringRedisConfig:
package com.javacodegeeks.spring.redis; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; @Configuration public class SpringRedisConfig { @Bean public JedisConnectionFactory connectionFactory() { JedisConnectionFactory connectionFactory = new JedisConnectionFactory(); connectionFactory.setHostName("localhost"); connectionFactory.setPort(6379); return connectionFactory; } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(connectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); return redisTemplate; } }
It performs automatic serialization/deserialization between the given objects and the underlying binary data in the Redis store. By default, it uses Java serialization for its objects.
9. Set and Get Object using Redis ValueOperations
Redis deals directly with byte arrays and doesn’t natively perform Object to byte[] translation. By default spring uses Java serialization. In the below example, we want to store Employee
object as it is and retrieve it later.
Employee:
package com.javacodegeeks.spring.redis; import java.io.Serializable; public class Employee implements Serializable { private static final long serialVersionUID = 1L; private String id; private String name; private Integer age; public Employee(){} public Employee(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String toString() { return "Employee [" + getId() + ", " + getName() + "]"; } }
Since Redis supports various operations like list operations, set operations, value operations etc, it provides sub-interfaces to deal with each use case. Since we want to set and get values, we’ll be using the ValueOperations template which we will be getting using RedisTemplate.opsForValue()
.
SpringRedisExample:
package com.javacodegeeks.spring.redis; import java.net.URISyntaxException; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; public class SpringRedisExample { public static void main(String[] args) throws URISyntaxException, Exception { ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext( SpringRedisConfig.class); try { RedisTemplate redisTemplate = (RedisTemplate) ctx.getBean("redisTemplate"); ValueOperations values = redisTemplate.opsForValue(); values.set("joe", new Employee("01", "Joe")); System.out.println("Employee added: " + values.get("joe")); } finally { ctx.close(); } } }
Output:
Jan 06, 2016 11:10:01 AM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6576fe71: startup date [Wed Jan 06 11:10:01 IST 2016]; root of context hierarchy Employee added: Employee [01, Joe] Jan 06, 2016 11:10:01 AM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6576fe71: startup date [Wed Jan 06 11:10:01 IST 2016]; root of context hierarchy
10. StringRedisTemplate Example
If you’re going to be dealing largely with Strings, the it is better to use the specific template class StringRedisTemplate
.
Let’s modify the config class. Add strRedisTemplate()
to it to return StringRedisTemplate
object.
SpringRedisConfig:
package com.javacodegeeks.spring.redis; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class SpringRedisConfig { @Bean public JedisConnectionFactory connectionFactory() { JedisConnectionFactory connectionFactory = new JedisConnectionFactory(); connectionFactory.setHostName("localhost"); connectionFactory.setPort(6379); return connectionFactory; } @Bean public RedisTemplate redisTemplate() { RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setConnectionFactory(connectionFactory()); return redisTemplate; } @Bean public StringRedisTemplate strRedisTemplate() { StringRedisTemplate redisTemplate = new StringRedisTemplate(); redisTemplate.setConnectionFactory(connectionFactory()); return redisTemplate; } }
SpringStringRedisExample:
package com.javacodegeeks.spring.redis; import java.net.URISyntaxException; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; public class SpringStringRedisExample { public static void main(String[] args) throws URISyntaxException, Exception { ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext( SpringRedisConfig.class); try { StringRedisTemplate redisTemplate = (StringRedisTemplate) ctx.getBean("strRedisTemplate"); ValueOperations values = redisTemplate.opsForValue(); values.set("01", "Joe"); values.set("02", "John"); System.out.println("Employee added: " + values.get("01")); System.out.println("Employee added: " + values.get("02")); } finally { ctx.close(); } } }
Output:
Jan 06, 2016 11:21:22 AM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6576fe71: startup date [Wed Jan 06 11:21:22 IST 2016]; root of context hierarchy Employee added: Joe Employee added: John Jan 06, 2016 11:21:23 AM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6576fe71: startup date [Wed Jan 06 11:21:22 IST 2016]; root of context hierarchy
11. Redis Hash Operations Example
In this example, we will use the Redis hash operations to store a map of attributes against a hash key. These attributes might be properties of a POJO class. This way we can store retrieves related properties with ease. Call RedisTemplate.opsForHash()
to get the hash operations object.
SpringRedisHashExample:
package com.javacodegeeks.spring.redis; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.StringRedisTemplate; public class SpringRedisHashExample { public static void main(String[] args) throws URISyntaxException, Exception { ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext( SpringRedisConfig.class); try { StringRedisTemplate redisTemplate = (StringRedisTemplate) ctx.getBean("strRedisTemplate"); HashOperations<String, String, String> hash = redisTemplate.opsForHash(); String empJoeKey = "emp:joe"; String empJohnKey = "emp:john"; Map<String, String> empJoeMap = new HashMap<>(); empJoeMap.put("name", "Joe"); empJoeMap.put("age", "32"); empJoeMap.put("id", "01"); Map<String, String> empJohnMap = new HashMap<>(); empJohnMap.put("name", "John"); empJohnMap.put("age", "42"); empJohnMap.put("id", "02"); hash.putAll(empJoeKey, empJoeMap); hash.putAll(empJohnKey, empJohnMap); System.out.println("Get emp joe details: " + hash.entries(empJoeKey)); System.out.println("Get emp john details: " + hash.entries(empJohnKey)); } finally { ctx.close(); } } }
Output:
Jan 06, 2016 12:24:03 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6576fe71: startup date [Wed Jan 06 12:24:03 IST 2016]; root of context hierarchy Get emp joe details: {id=01, age=32, name=Joe} Get emp john details: {age=42, name=John, id=02} Jan 06, 2016 12:24:03 PM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6576fe71: startup date [Wed Jan 06 12:24:03 IST 2016]; root of context hierarchy
12. Redis AtomicLong Example
In case of distributed application, there may be scenarios where we need a unique number which is unique across the applications in cluster. Spring Data Redis uses the value operations internally to manage the atomic numbers like AtomicInteger
, AtomicLong
and backs the current by a Redis instance. This way we can always generate a unique number irrespective of the JVM. In thebelow example, we use instance of RedisAtomicLong
to get the current long number set against a key and increment it atomically.
SpringRedisAtomicLongExample:
package com.javacodegeeks.spring.redis; import java.net.URISyntaxException; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.support.atomic.RedisAtomicLong; public class SpringRedisAtomicLongExample { public static void main(String[] args) throws URISyntaxException, Exception { ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext( SpringRedisConfig.class); try { RedisConnectionFactory connectionFactory = (RedisConnectionFactory) ctx.getBean("connectionFactory"); RedisAtomicLong uniqueNbr = new RedisAtomicLong("RedisUniqueNbr", connectionFactory, 0); System.out.println("Redis Atomic Long: " + uniqueNbr.incrementAndGet()); } finally { ctx.close(); } } }
Output:
Jan 06, 2016 2:21:50 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@45c8e616: startup date [Wed Jan 06 14:21:50 IST 2016]; root of context hierarchy Redis Atomic Long: 1 Jan 06, 2016 2:22:27 PM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@45c8e616: startup date [Wed Jan 06 14:21:50 IST 2016]; root of context hierarchy
13. Download the source code
This was an example about Spring Data Redis.
You can download the full source code of this example here: springRedisExample.zip