有趣的地方

有趣的地方

SpringBoot | 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 下载安装

3. 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> , T表示实体类对象类型; ID表示实体类中的主键的“类型”
    public interface PersonRepository extends CrudRepository<Person,String> { //Person类对应的"Repository接口" : 该接口中为"操作数据库"的"方法"
    
        /**
         * 使用"方法名关键字" 的方式进行数据操作 :
         *
         */
        //根据lastname属性值进行数据查询
        //相当于 select * from 表名 where lastname = ?1
        List<Person> findByLastname(String lastname);
    
        //根据lastname属性进行“分页查询”
        //findPersonByLastname 中的 Person表示“最后的返回值”为Person类型对象 (当然还要结合形成“分页效果”)
        Page<Person> findPersonByLastname(String lastname, Pageable page);
    
        //根据firstname 和 lastname两个参数进行数据查询
        //相当于 select * from 表名 where firstname = ?1 and lastname = ?2
        List<Person> findByFirstnameAndLastname(String firstname, String lastname);
    
        /*
           根据city属性进行查询 (但这个city属性为Person对象中的Address对象类型属性中的子属性),所以用Address_City这种表示形式
           findByAddress_City 本质上和 findByLastname 都是“同一种” "方法名关键字查询"的方式 (Address_City 表示 Address对象属性中的子属性)
         */
        List<Person> findByAddress_City(String city); //根据City属性查询数据
    
        /*
           findByFamilyList_Username 本质上和 findByLastname
           都是“同一种” "方法名关键字查询"的方式 (FamilyList_Username 表示 Family对象属性中的子属性)
         */
        List<Person> findByFamilyList_Username(String usernmae); //根据usernmae属性查询数据
    
    }
    

    上面的代码中PersonRepository接口 继承CrudRepository接口,该接口中定义了若干查询方法。需要说明的是,在 操作Redis 数据库时编写的 Reposiitory 接口 文件 需要继承CrudRepository接口,而 不是继承JpaRepository,这是因为 JpaReposiitorySpring 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服务地址为本机( localhost127.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<Family> 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<Family> getFamilyList() {
            return familyList;
        }
    
        public void setFamilyList(List<Family> 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<Family> 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> , T表示实体类对象类型; ID表示实体类中的主键的“类型”
    public interface PersonRepository extends CrudRepository<Person,String> { //Person类对应的"Repository接口" : 该接口中为"操作数据库"的"方法"
    
        /**
         * 使用"方法名关键字" 的方式进行数据操作 :
         *
         */
        //根据lastname属性值进行数据查询
        //相当于 select * from 表名 where lastname = ?1
        List<Person> findByLastname(String lastname);
    
        //根据lastname属性进行“分页查询”
        //findPersonByLastname 中的 Person表示“最后的返回值”为Person类型对象 (当然还要结合形成“分页效果”)
        Page<Person> findPersonByLastname(String lastname, Pageable page);
    
        //根据firstname 和 lastname两个参数进行数据查询
        //相当于 select * from 表名 where firstname = ?1 and lastname = ?2
        List<Person> findByFirstnameAndLastname(String firstname, String lastname);
    
        /*
           根据city属性进行查询 (但这个city属性为Person对象中的Address对象类型属性中的子属性),所以用Address_City这种表示形式
           findByAddress_City 本质上和 findByLastname 都是“同一种” "方法名关键字查询"的方式 (Address_City 表示 Address对象属性中的子属性)
         */
        List<Person> findByAddress_City(String city); //根据City属性查询数据
    
        /*
           findByFamilyList_Username 本质上和 findByLastname
           都是“同一种” "方法名关键字查询"的方式 (FamilyList_Username 表示 Family对象属性中的子属性)
         */
        List<Person> 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 :

    <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.myh</groupId>
        <artifactId>chapter_08</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>chapter_08</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.28</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>RELEASE</version>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    
    <!--    <build>-->
    <!--        <plugins>-->
    <!--            <plugin>-->
    <!--                <groupId>org.springframework.boot</groupId>-->
    <!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
    <!--            </plugin>-->
    <!--        </plugins>-->
    <!--    </build>-->
    
    </project>
    

    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<Family> 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<Person> 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数据库中的数据成功!");
        }
    }
    

发表评论:

Powered By Z-BlogPHP 1.7.3

© 2018-2020 有趣的地方 粤ICP备18140861号-1 网站地图