diff --git a/persistence-modules/redis/pom.xml b/persistence-modules/redis/pom.xml
index fffcfbb96b..c9206e5f92 100644
--- a/persistence-modules/redis/pom.xml
+++ b/persistence-modules/redis/pom.xml
@@ -9,16 +9,31 @@
com.baeldung
- persistence-modules
- 1.0.0-SNAPSHOT
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
redis.clients
jedis
- ${jedis.version}
-
+
com.github.kstyrc
embedded-redis
@@ -32,15 +47,12 @@
io.lettuce
lettuce-core
- ${lettuce-core.version}
-
+
-
- 3.2.0
+
0.6
- 3.3.0
- 5.0.1.RELEASE
+ 3.3.0
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/RedisConfig.java b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/RedisConfig.java
new file mode 100644
index 0000000000..ad43ad8159
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/RedisConfig.java
@@ -0,0 +1,24 @@
+package com.baeldung.spring.redis.configuration;
+
+import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import com.baeldung.spring.redis.configuration.entity.Book;
+
+@Configuration
+@EnableConfigurationProperties(RedisProperties.class)
+public class RedisConfig {
+
+ @Bean
+ public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
+ RedisTemplate template = new RedisTemplate<>();
+ template.setConnectionFactory(connectionFactory);
+ // Add some specific configuration here. Key serializers, etc.
+ return template;
+ }
+
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/SpringRedisConfigurationApplication.java b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/SpringRedisConfigurationApplication.java
new file mode 100644
index 0000000000..932a6b7478
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/SpringRedisConfigurationApplication.java
@@ -0,0 +1,19 @@
+package com.baeldung.spring.redis.configuration;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringRedisConfigurationApplication implements CommandLineRunner {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringRedisConfigurationApplication.class, args);
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+
+ }
+
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/controller/BooksController.java b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/controller/BooksController.java
new file mode 100644
index 0000000000..b3faf030c9
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/controller/BooksController.java
@@ -0,0 +1,32 @@
+package com.baeldung.spring.redis.configuration.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.spring.redis.configuration.entity.Book;
+import com.baeldung.spring.redis.configuration.repository.BooksRepository;
+
+@RestController
+@RequestMapping("/books")
+public class BooksController {
+
+ @Autowired
+ private BooksRepository repository;
+
+ @PostMapping("/create")
+ public String newBook(@RequestBody Book newBook) {
+ repository.save(newBook);
+ return "Added";
+ }
+
+ @GetMapping("/get/{id}")
+ public Book findOne(@PathVariable Long id) {
+ return repository.findById(id);
+ }
+
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/entity/Book.java b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/entity/Book.java
new file mode 100644
index 0000000000..52d579d4fb
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/entity/Book.java
@@ -0,0 +1,46 @@
+package com.baeldung.spring.redis.configuration.entity;
+
+import java.io.Serializable;
+
+public class Book implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private String name;
+
+ public Book() {
+ }
+
+ public Book(String name) {
+ this.name = name;
+ }
+
+ public Book(Long id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "Book [id=" + id + ", name=" + name + "]";
+ }
+
+}
diff --git a/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/repository/BooksRepository.java b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/repository/BooksRepository.java
new file mode 100644
index 0000000000..a6eba0e742
--- /dev/null
+++ b/persistence-modules/redis/src/main/java/com/baeldung/spring/redis/configuration/repository/BooksRepository.java
@@ -0,0 +1,25 @@
+package com.baeldung.spring.redis.configuration.repository;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import com.baeldung.spring.redis.configuration.entity.Book;
+
+@Component
+public class BooksRepository {
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ public void save(Book book) {
+ redisTemplate.opsForValue()
+ .set(book.getId(), book);
+ }
+
+ public Book findById(Long id) {
+ return redisTemplate.opsForValue()
+ .get(id);
+ }
+
+}
diff --git a/persistence-modules/redis/src/main/resources/application.properties b/persistence-modules/redis/src/main/resources/application.properties
new file mode 100644
index 0000000000..e3140c4e29
--- /dev/null
+++ b/persistence-modules/redis/src/main/resources/application.properties
@@ -0,0 +1,9 @@
+spring.redis.database=0
+spring.redis.host=localhost
+spring.redis.port=16379
+spring.redis.password=mypass
+spring.redis.timeout=60000
+spring.redis.lettuce.pool.max-active=8
+spring.redis.lettuce.pool.max-idle=8
+spring.redis.lettuce.pool.max-wait=-1
+spring.redis.lettuce.pool.min-idle=0
\ No newline at end of file
diff --git a/persistence-modules/redis/src/test/java/com/baeldung/spring/redis/configuration/controller/BooksControllerUnitTest.java b/persistence-modules/redis/src/test/java/com/baeldung/spring/redis/configuration/controller/BooksControllerUnitTest.java
new file mode 100644
index 0000000000..a5c3340065
--- /dev/null
+++ b/persistence-modules/redis/src/test/java/com/baeldung/spring/redis/configuration/controller/BooksControllerUnitTest.java
@@ -0,0 +1,52 @@
+package com.baeldung.spring.redis.configuration.controller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.spring.redis.configuration.entity.Book;
+import com.baeldung.spring.redis.configuration.repository.BooksRepository;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+public class BooksControllerUnitTest {
+
+ @Spy
+ @InjectMocks
+ private BooksController booksController;
+
+ @Mock
+ private BooksRepository booksRepository;
+
+ private static final Long BOOK_ID = 1l;
+ private static final Long OTHER_BOOK_ID = 2l;
+ private static final String BOOK_NAME = "Ulysses";
+ private static final String ADDED = "Added";
+
+ @Test
+ public void whenNewBook_thenCorrect() {
+ assertEquals(ADDED, booksController.newBook(new Book(BOOK_ID, BOOK_NAME)));
+ }
+
+ @Test
+ public void whenFindOneFinds_thenCorrect() {
+ Book book = new Book(BOOK_ID, BOOK_NAME);
+ when(booksRepository.findById(BOOK_ID)).thenReturn(book);
+ assertSame(book, booksController.findOne(BOOK_ID));
+ }
+
+ @Test
+ public void whenFindOneNotFound_thenReturnsNull() {
+ Book book = new Book(BOOK_ID, BOOK_NAME);
+ when(booksRepository.findById(BOOK_ID)).thenReturn(book);
+ assertNull(booksController.findOne(OTHER_BOOK_ID));
+ }
+
+}
diff --git a/persistence-modules/redis/src/test/java/com/baeldung/spring/redis/configuration/repository/BooksRepositoryUnitTest.java b/persistence-modules/redis/src/test/java/com/baeldung/spring/redis/configuration/repository/BooksRepositoryUnitTest.java
new file mode 100644
index 0000000000..1edf9c7e89
--- /dev/null
+++ b/persistence-modules/redis/src/test/java/com/baeldung/spring/redis/configuration/repository/BooksRepositoryUnitTest.java
@@ -0,0 +1,66 @@
+package com.baeldung.spring.redis.configuration.repository;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.spring.redis.configuration.entity.Book;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+public class BooksRepositoryUnitTest {
+
+ @Spy
+ @InjectMocks
+ private BooksRepository booksRepository;
+
+ @Mock
+ private RedisTemplate redisTemplate;
+
+ @Mock
+ private ValueOperations valueOperations;
+
+ private static final Long BOOK_ID = 1l;
+ private static final Long OTHER_BOOK_ID = 2l;
+ private static final String BOOK_NAME = "Ulysses";
+
+ @Test
+ public void whenSave_thenCorrect() {
+ Book book = new Book(BOOK_ID, BOOK_NAME);
+ when(redisTemplate.opsForValue()).thenReturn(valueOperations);
+ booksRepository.save(book);
+ verify(redisTemplate, times(1)).opsForValue();
+ verify(valueOperations, times(1)).set(BOOK_ID, book);
+ }
+
+ @Test
+ public void whenFindByIdFound_thenReturnsBook() {
+ Book book = new Book(BOOK_ID, BOOK_NAME);
+ when(redisTemplate.opsForValue()).thenReturn(valueOperations);
+ when(valueOperations.get(BOOK_ID)).thenReturn(book);
+ assertSame(book, booksRepository.findById(BOOK_ID));
+ verify(redisTemplate, times(1)).opsForValue();
+ verify(valueOperations, times(1)).get(BOOK_ID);
+ }
+
+ @Test
+ public void whenFindByIdNotFound_thenReturnsNull() {
+ Book book = new Book(BOOK_ID, BOOK_NAME);
+ when(redisTemplate.opsForValue()).thenReturn(valueOperations);
+ when(valueOperations.get(BOOK_ID)).thenReturn(book);
+ assertNull(booksRepository.findById(OTHER_BOOK_ID));
+ verify(redisTemplate, times(1)).opsForValue();
+ verify(valueOperations, times(1)).get(OTHER_BOOK_ID);
+ }
+
+}