目录:
- 1. Redis 介绍
- 2. Redis 下载安装
- 3. Redis “服务开启”和“连接配置”
- 4. Spring Boot整合Redis的“前期准备” :
- ① 编写实体类
- ② 编写Repository 接口
- ③ 在“全局配置文件”中添加 “Redis数据库” 的 “相关配置信息”
- 5. Spring Boot整合“Redis” (案例展示)
作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!
该文章参考学习教材为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章
文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!
(侵权可联系我,进行删除,如果雷同,纯属巧合)
- Spring Boot 除了 对 关系型数据库 的 整合支持 外,Spring Boot对 非关系型数据库 也提供了非常好的支持。如 : Spring Boot对 非关系型数据库Redis 的 整合使用。
1. Redis 介绍
-
Redis 是一个 开源(BSD 许可)的、内存 中的 数据结构存储系统 ,它可以用作 数据库、缓存和消息中间件,并提供多种语言的API。
-
Redis 支持 多种类型的数据结构,例如 字符串(strings)、散列( hashes )、列表( lists )、集合( sets)等。同时,Redis内部内置了复本(replication)、LUA 脚本( Lua scripting )、LRU 驱动事件( LRU eviction )、事务(Transaction)和 不同级别的磁盘持久化( persistence ),并通过Redis Sentinel 和 自动分区提供高可用性( high availability )。相较于其他的 key-value 键值存储系统而言,
Redis主要有以下优点 :
① 存取速度快 : Redis 速度非常快,每秒可执行大约 110000次 的 设值操作,或者执行 81000 次的 读取操作。
② 支持丰富的数据类型 : Redis 支持开发人员常用的大多数数据类型,例如列表、集合、排序集和散列等。
③ 操作具有原子性 : 所有 Redis 操作 都是 原子操作,这确保如果两个客户端并发访问,Redis服务器能接收更新后的值。
④ 提供多种功能 : Redis 提供了多种功能特性,可用作非关系型数据库、缓存中间件、消息中间件等。
2. Redis 下载安装
- Redis下载安装 :
Redis入门 (Redis下载安装)-跳转博客
3. Redis “服务开启”和“连接配置”
-
完成 Redis 的下载安装后,启动Redis 服务,并使用 可视化客户端工具 连接对应的Redis
服务进行效果测试,具体操作步骤如下 :
(1) 开启Redis服务
(2) Redis可视化客户端工具正常安装连接
Redis入门 (Redis “服务开启”和“连接配置”)-跳转博客
4. Spring Boot整合Redis的“前期准备” :
① 编写实体类
-
编写实体类中最重要的是懂得使用SpringBoot整合Redis中的常用注解 :
注解 描述 @RedisHash( " 存储空间的名称" )注解 用于指定操作 实体类对象 在 Redis 数据库 中的 存储空间。
如:
@RedisHash(“persons”) 表示此处的的Redis数据都存储在 Redis 数据库中 名为 persons 的 存储空间 下。@ld注解 用于 标识实体类 “主键”。在Redis数据库中会 默认生成“字符串形式” 的 HashKey 表示 唯一 的实体对象id,当然也可以在数据存储时 手动指定id。 @Indexed注解 用于 标识 “对应属性” 在Redis数据库中 生成二级索引。使用该注解后会在Redis数据库中生成属性对应的二级索引,索引名称就是属性名,可以方便地进行数据条件查询。 -
例子如 :
person.java( 实体类 ) :
package com.myh.chapter_08.domain; import org.springframework.data.annotation.Id; import org.springframework.data.redis.core.RedisHash; import org.springframework.data.redis.core.index.Indexed; @RedisHash("RedisPersonInfo") //将要存储的数据都存储在Redis数据库中的RedisPersonInfo的这个命名空间下 public class Person { @Id //标识“实体类”的“主键” private String id; //在redis数据库中生成“属性”对应的“二级索引” @Indexed //表述该属性,在redis数据库中生成"二级索引" (“索引名”就是“属性名”) private String firstname; @Indexed //在数据库中生成“属性”对应的“二级索引” private String lastname; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } @Override public String toString() { return "Person{" + "id='" + id + '\'' + ", firstname='" + firstname + '\'' + ", lastname='" + lastname + '\'' + '}'; } public Person(String id, String firstname, String lastname) { this.id = id; this.firstname = firstname; this.lastname = lastname; } public Person() { //无参构造方法 } }
Address.java :
package com.myh.chapter_08.domain; import org.springframework.data.annotation.Id; import org.springframework.data.redis.core.RedisHash; import org.springframework.data.redis.core.index.Indexed; public class Address { @Indexed //表述该属性,在redis数据库中生成"二级索引" (“索引名”就是“属性名”) private String city; @Indexed //在数据库中生成“属性”对应的“二级索引” private String country; public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } @Override public String toString() { return "Address{" + "city='" + city + '\'' + ", country='" + country + '\'' + '}'; } public Address(String city, String country) { this.city = city; this.country = country; } public Address() { } }
Address.java :
package com.myh.chapter_08.domain; import org.springframework.data.redis.core.index.Indexed; public class Family { @Indexed private String type; @Indexed private String username; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Family(String type) { this.type = type; } @Override public String toString() { return "Family{" + "type='" + type + '\'' + ", username='" + username + '\'' + '}'; } public Family(String type, String username) { this.type = type; this.username = username; } public Family() { //无参构造方法 } }
② 编写Repository 接口
-
Spring Boot 针对包括 Redis在内 的一些 常用数据库 提供了 自动化配置,可以通过 实现 Repository接口 简化 对数据库中的数据进行的 增删改查操作,这些操作方法同 Spring Data JPA操作数据的使用方法基本相同,可以使用方法名关键字进行数据操作。
(方法名关键字查询(也称为 方法名约定查询)是一种 约定大于配置 的 查询方式。这种方式允许开发者通过简单的方法命名来定义查询 ( 方法的命名是有一定的规律的 ) )
-
例子如:
PersonRepository.java ( Repository接口 )
package com.myh.chapter_08.Repository.Repository; import com.myh.chapter_08.domain.Person; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; import java.util.List; //CrudRepository
, T表示实体类对象类型; ID表示实体类中的主键的“类型” public interface PersonRepository extends CrudRepository { //Person类对应的"Repository接口" : 该接口中为"操作数据库"的"方法" /** * 使用"方法名关键字" 的方式进行数据操作 : * */ //根据lastname属性值进行数据查询 //相当于 select * from 表名 where lastname = ?1 List findByLastname(String lastname); //根据lastname属性进行“分页查询” //findPersonByLastname 中的 Person表示“最后的返回值”为Person类型对象 (当然还要结合形成“分页效果”) Page findPersonByLastname(String lastname, Pageable page); //根据firstname 和 lastname两个参数进行数据查询 //相当于 select * from 表名 where firstname = ?1 and lastname = ?2 List findByFirstnameAndLastname(String firstname, String lastname); /* 根据city属性进行查询 (但这个city属性为Person对象中的Address对象类型属性中的子属性),所以用Address_City这种表示形式 findByAddress_City 本质上和 findByLastname 都是“同一种” "方法名关键字查询"的方式 (Address_City 表示 Address对象属性中的子属性) */ List findByAddress_City(String city); //根据City属性查询数据 /* findByFamilyList_Username 本质上和 findByLastname 都是“同一种” "方法名关键字查询"的方式 (FamilyList_Username 表示 Family对象属性中的子属性) */ List findByFamilyList_Username(String usernmae); //根据usernmae属性查询数据 } 在上面的代码中,PersonRepository接口 继承 自 CrudRepository接口,该接口中定义了若干查询方法。需要说明的是,在 操作Redis 数据库时编写的 Reposiitory 接口 文件 需要继承CrudRepository接口,而 不是继承JpaRepository,这是因为 JpaReposiitory 是 Spring Boot 整合 JPA特有的。当然,也可以在项目pom.xml 文件中同时导入Spring Boot 整合的 JPA 依赖和 Redis依赖,这样就可以编写一个继承JpaRepository 的接口操作 Redis数据库了。
③ 在“全局配置文件”中添加 “Redis数据库” 的 “相关配置信息”
#配置Redis数据库连接信息/连接参数 #Redis服务器地址 spring.redis.host = 127.0.0.1 #Redis服务器连接端口(默认为6379) spring.redis.port=6379 #Redis服务连接器密码(默认为空) spring.redis.password=root
上述代码中,在Spring Boot项目的全局配置文件application.properties 中额外添加了 Redis数据库的相关配置信息,这与之前介绍的使用 Redis 客户端可视化工具连接 时 设置的参数基本一致。除了一些基本配置外,还可以根据需要添加Redis数据库相关的其他配置。
注意点 :
在上述示例 application.properties 中主要配置了Redis数据库的 服务地址 和 端口号,而Spring Boot内部默认 Redis服务地址为本机( localhost 或 127.0.0.1),服务端口号为6379,这与前面开启的Redis服务一致,所以这种情况下省略上述配置,仍可以正常连接访问本地开启的Redis服务。
5. Spring Boot整合“Redis” (案例展示)
-
Spring Boot整合“Redis” ,例子如 :
创建项目 :
Address.java :
package com.myh.chapter_08.domain; import org.springframework.data.annotation.Id; import org.springframework.data.redis.core.RedisHash; import org.springframework.data.redis.core.index.Indexed; public class Address { @Indexed //表述该属性,在redis数据库中生成"二级索引" (“索引名”就是“属性名”) private String city; @Indexed //在数据库中生成“属性”对应的“二级索引” private String country; //省略属性的get、set方法 //省略有参和无参构造方法 //省略toString()方法 public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } @Override public String toString() { return "Address{" + "city='" + city + '\'' + ", country='" + country + '\'' + '}'; } public Address(String city, String country) { this.city = city; this.country = country; } public Address() { } }
Family.java :
package com.myh.chapter_08.domain; import org.springframework.data.redis.core.index.Indexed; public class Family { @Indexed private String type; @Indexed private String username; //省略属性的get、set方法 //省略有参和无参构造方法 //省略toString()方法 public String getType() { return type; } public void setType(String type) { this.type = type; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Family(String type) { this.type = type; } @Override public String toString() { return "Family{" + "type='" + type + '\'' + ", username='" + username + '\'' + '}'; } public Family(String type, String username) { this.type = type; this.username = username; } public Family() { //无参构造方法 } }
Person.java :
package com.myh.chapter_08.domain; import org.springframework.data.annotation.Id; import org.springframework.data.redis.core.RedisHash; import org.springframework.data.redis.core.index.Indexed; import java.util.List; @RedisHash("RedisPersonInfo") //将要存储的数据都存储在Redis数据库中的RedisPersonInfo的这个命名空间下 public class Person { @Id //标识“实体类”的“主键” private String id; //在redis数据库中生成“属性”对应的“二级索引” @Indexed //表述该属性,在redis数据库中生成"二级索引" (“索引名”就是“属性名”) private String firstname; @Indexed //在数据库中生成“属性”对应的“二级索引” private String lastname; private Address address; private List
familyList; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public List getFamilyList() { return familyList; } public void setFamilyList(List familyList) { this.familyList = familyList; } @Override public String toString() { return "Person{" + "id='" + id + '\'' + ", firstname='" + firstname + '\'' + ", lastname='" + lastname + '\'' + ", address=" + address + ", familyList=" + familyList + '}'; } public Person(String id, String firstname, String lastname, Address address, List familyList) { this.id = id; this.firstname = firstname; this.lastname = lastname; this.address = address; this.familyList = familyList; } public Person() { //无参构造方法 } public Person(String firstname, String lastname) { this.firstname = firstname; this.lastname = lastname; } } PersonRepository.java :
package com.myh.chapter_08.Repository.Repository; import com.myh.chapter_08.domain.Person; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; import java.util.List; //CrudRepository
, T表示实体类对象类型; ID表示实体类中的主键的“类型” public interface PersonRepository extends CrudRepository { //Person类对应的"Repository接口" : 该接口中为"操作数据库"的"方法" /** * 使用"方法名关键字" 的方式进行数据操作 : * */ //根据lastname属性值进行数据查询 //相当于 select * from 表名 where lastname = ?1 List findByLastname(String lastname); //根据lastname属性进行“分页查询” //findPersonByLastname 中的 Person表示“最后的返回值”为Person类型对象 (当然还要结合形成“分页效果”) Page findPersonByLastname(String lastname, Pageable page); //根据firstname 和 lastname两个参数进行数据查询 //相当于 select * from 表名 where firstname = ?1 and lastname = ?2 List findByFirstnameAndLastname(String firstname, String lastname); /* 根据city属性进行查询 (但这个city属性为Person对象中的Address对象类型属性中的子属性),所以用Address_City这种表示形式 findByAddress_City 本质上和 findByLastname 都是“同一种” "方法名关键字查询"的方式 (Address_City 表示 Address对象属性中的子属性) */ List findByAddress_City(String city); //根据City属性查询数据 /* findByFamilyList_Username 本质上和 findByLastname 都是“同一种” "方法名关键字查询"的方式 (FamilyList_Username 表示 Family对象属性中的子属性) */ List findByFamilyList_Username(String usernmae); //根据usernmae属性查询数据 } application.properties :
#配置Redis数据库连接信息/连接参数 #Redis服务器地址 spring.redis.host = 127.0.0.1 #Redis服务器连接端口(默认为6379) spring.redis.port=6379 #Redis服务连接器密码(默认为空) spring.redis.password=root
pom.xml :
4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.myh chapter_08 0.0.1-SNAPSHOT chapter_08 Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-data-redis mysql mysql-connector-java 8.0.28 org.springframework.boot spring-boot-starter-test test org.junit.jupiter junit-jupiter RELEASE test Chapter08ApplicationTests.java :
package com.myh.chapter_08; import com.myh.chapter_08.Repository.Repository.PersonRepository; import com.myh.chapter_08.domain.Address; import com.myh.chapter_08.domain.Family; import com.myh.chapter_08.domain.Person; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest class Chapter08ApplicationTests { @Autowired private PersonRepository personRepository; @Test public void savePerson() { Person person = new Person("张", "有才"); Person person2 = new Person("James", "Harden"); //创建并添加地址信息 Address address = new Address("北京", "China"); person.setAddress(address); //创建并添加家庭成员 List
list = new ArrayList<>(); Family dad = new Family("父亲", "张良"); Family mom = new Family("母亲", "李香君"); list.add(dad); list.add(mom); person.setFamilyList(list); //向Redis数据库添加数据 Person save = personRepository.save(person); Person save2 = personRepository.save(person2); System.out.println(save); System.out.println(save2); System.out.println("向Redis数据库中插入成功"); } @Test public void selectPerson() { List list = personRepository.findByAddress_City("北京"); System.out.println(list); } @Test public void updatePerson() { Person person = personRepository.findByFirstnameAndLastname("张", "有才").get(0); //修改该对象的属性值 person.setLastname("小明"); Person update = personRepository.save(person); System.out.println(update); } @Test public void deletePerson() { Person person = personRepository.findByFirstnameAndLastname("张", "小明").get(0); personRepository.delete(person);//删除Redis数据库中的数据 System.out.println("删除Redis数据库中的数据成功!"); } }