使用Spring Boot整合Redis
上一小节对Redis进行了简单介绍,并完成了Redis服务的安装配置,接下来,重点讲解Spring Boot与Redis的整合使用,具体步骤如下。
(1)添加Spring Data Redis依赖启动器。先在项目的pom.xml文件中添加Spring Data Redis依赖启动器,示例代码如下。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
上述添加的Spring Data Redis依赖启动器代码中,也没有编写对应的版本号信息,这是因为Spring Boot为Redis实现了自动配置,所以会统一管理版本号信息。
(2)编写实体类。此处为了演示Spring Boot与Redis数据库的整合使用,在chapter03项目的com.itheima.domain包下编写几个对应的实体类,内容如文件1、2和3所示。
文件1 Person.java
1 import org.springframework.data.annotation.Id;
2 import org.springframework.data.redis.core.RedisHash;
3 import org.springframework.data.redis.core.index.Indexed;
4 import java.util.List;
5 @RedisHash("persons") // 指定操作实体类对象在Redis数据库中的存储空间
6 public class Person {
7 @Id // 标识实体类主键
8 private String id;
9 @Indexed // 标识对应属性在Redis数据库中生成二级索引
10 private String firstname;
11 @Indexed
12 private String lastname;
13 private Address address;
14 private List<Family> familyList;
15 // 省略属性getXX()和setXX()方法
16 // 省略有参和无参构造方法
17 // 省略toString()方法
18 }
文件2 Address.java
1 import org.springframework.data.redis.core.index.Indexed;
2 public class Address {
3 @Indexed
4 private String city;
5 @Indexed
6 private String country;
7 // 省略属性getXX()和setXX()方法
8 // 省略有参和无参构造方法
9 // 省略toString()方法
10 }
文件3 Family.java
1 import org.springframework.data.redis.core.index.Indexed;
2 public class Family {
3 @Indexed
4 private String type;
5 @Indexed
6 private String username;
7 // 省略属性getXX()和setXX()方法
8 // 省略有参和无参构造方法
9 // 省略toString()方法
10 }
文件1、2和3编写的实体类示例中,针对面向Redis数据库的数据操作设置了几个主要注解,这几个注解的说明如下。
● @RedisHash("persons"):用于指定操作实体类对象在Redis数据库中的存储空间,此处表示针对Person实体类的数据操作都存储在Redis数据库中名为persons的存储空间下。
● @Id:用于标识实体类主键。在Redis数据库中会默认生成字符串形式的HashKey表示唯一的实体对象id,当然也可以在数据存储时手动指定id。
● @Indexed:用于标识对应属性在Redis数据库中生成二级索引。使用该注解后会在Redis数据库中生成属性对应的二级索引,索引名称就是属性名,可以方便的进行数据条件查询。
(3)编写Repository接口。Spring Boot针对包括Redis在内的一些常用数据库提供了自动化配置,可以通过实现Repository接口简化对数据库中的数据进行增删改查操作,这些操作方法同上一小节中讲解的Spring Data JPA操作数据的使用基本相同,可以使用方法名关键字进行数据操作。这里,在com.itheima.repository包下,创建操作Person实体类的PersonRepository接口,内容如文件4所示。
文件4 PersonRepository.java
1 import com.itheima.domain.Person;
2 import org.springframework.data.domain.Page;
3 import org.springframework.data.domain.Pageable;
4 import org.springframework.data.repository.CrudRepository;
5 import java.util.List;
6 public interface PersonRepository extends CrudRepository<Person, String> {
7 List<Person> findByLastname(String lastname);
8 Page<Person> findPersonByLastname(String lastname, Pageable page);
9 List<Person> findByFirstnameAndLastname(String firstname, String lastname);
10 List<Person> findByAddress_City(String city);
11 List<Person> findByFamilyList_Username(String username);
12 }
文件4中,PersonRepository接口继承自CrudRepository 接口,该接口定义了若干查询方法。
需要说明的是,在操作Redis数据库时编写的Repository接口文件需要继承最底层的CrudRepository接口,而不是继承JpaRepository,这是因为JpaRepository是Spring Boot整合JPA特有的。当然,也可以在项目pom.xml文件中同时导入Spring Boot整合的JPA依赖和Redis依赖,这样就可以编写一个继承JpaRepository的接口操作Redis数据库了。
(4)Redis数据库连接配置。在项目的全局配置文件application.properties中添加Redis数据库的连接配置,示例代码如下。
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
上述代码中,在Spring Boot项目的全局配置文件application.properties中额外添加了Redis数据库的相关配置信息,这与之前介绍的使用Redis客户端可视化工具连接时设置的参数基本一致。除了一些基本配置外,还可以根据需要添加Redis数据库相关的其他配置。
小提示:
在上述示例application.properties中主要配置了Redis数据库的服务地址和端口号,而Spring Boot内部默认Redis服务地址为本机(localhost或127.0.0.1),服务端口号为6379,这与前面开启的Redis服务一致,所以这种情况下省略上述配置,仍可以正常连接访问本地开启的Redis服务。
(5)编写单元测试进行接口方法测试。将Chapter03ApplicationTests测试类在当前位置复制一份并重命名为RedisTests,并对内容稍微修改后编写PersonRepository接口对应的测试方法,内容如文件5所示。
文件5 RedisTests.java
1 import org.springframework.beans.factory.annotation.Autowired;
2 ...
3 @RunWith(SpringRunner.class)
4 @SpringBootTest
5 public class RedisTests {
6 @Autowired
7 private PersonRepository repository;
8 @Test
9 public void savePerson() {
10 Person person =new Person("张","有才");
11 Person person2 =new Person("James","Harden");
12 // 创建并添加住址信息
13 Address address=new Address("北京","China");
14 person.setAddress(address);
15 // 创建并添加家庭成员
16 List<Family> list =new ArrayList<>();
17 Family dad =new Family("父亲","张良");
18 Family mom =new Family("母亲","李香君");
19 list.add(dad);
20 list.add(mom);
21 person.setFamilyList(list);
22 // 向Redis数据库添加数据
23 Person save = repository.save(person);
24 Person save2 = repository.save(person2);
25 System.out.println(save);
26 System.out.println(save2);
27 }
28 @Test
29 public void selectPerson() {
30 List<Person> list = repository.findByAddress_City("北京");
31 System.out.println(list);
32 }
33 @Test
34 public void updatePerson() {
35 Person person = repository.findByFirstnameAndLastname("张","有才").get(0);
36 person.setLastname("小明");
37 Person update = repository.save(person);
38 System.out.println(update);
39 }
40 @Test
41 public void deletePerson() {
42 Person person = repository.findByFirstnameAndLastname("张","小明").get(0);
43 repository.delete(person);
44 }
45 }
文件5中,通过注入的PersonRepository实例对象调用接口中的方法,实现了对Redis数据库数据的增删改查操作。
(6)整合测试。选择RedisTests测试类中的savePerson()方法进行效果演示,直接执行savePerson()方法,控制台效果如图1所示。
图1 savePerson()方法执行结果
从图1可以看出,savePerson()方法执行成功,并返回了向Redis数据库保存的两条Person实体类对象信息(包括自动生成的主键id)。
为了验证savePerson()方法的执行效果,还可以打开之前连接的Redis客户端可视化管理工具查看数据,效果如图2所示(可能需要右键选择数据库Reload选项刷新)。
图2 Redis数据库可视化展示
从图2可以看出,执行savePerson()方法添加的数据在Redis数据库中存储成功。另外,在数据库列表左侧还生成了一些类似address.city、firstname、lastname等二级索引,这些二级索引是前面创建Person类时在对应属性上添加@Indexed注解而生成的。同时,由于在Redis数据库中生成了对应属性的二级索引,所以可以通过二级索引来查询具体的数据信息,例如repository.findByAddress_City("北京")通过address.city索引查询索引值为“北京”的数据信息。如果没有设置对应属性的二级索引,那么通过属性索引查询数据结果将会为空。
至此,关于Spring Boot整合Redis数据库已讲解完毕,这里重点讲解的是Spring Boot与Redis数据库整合的基本使用,关于更多Redis的相关知识和其他操作,有兴趣的读者可以自行查看学习。