苍穹外卖05(Redis入门,下载于安装,服务启动和停止,Redis数据类型面试题,常用命令,Java中操作Redis,店铺营业状态设置)

目录

一、Redis入门

1. Redis简介

1 NoSQL介绍

2 Redis简介

2. Redis下载与安装

1 Redis下载

2 Redis安装

3. Redis服务启动与停止

1 服务启动命令

2 客户端连接命令

3 修改Redis配置文件

3 修改Redis配置文件

4 Redis客户端图形工具

二、Redis数据类型【面试题】

1. 五种常用数据类型介绍

2. 各种数据类型特点

3.Redis的数据类型及应用场景

三、Redis常用命令

1. 字符串操作命令

2. 哈希操作命令

3. 列表操作命令

4. 集合操作命令

5. 有序集合操作命令

6. 通用命令

7. 小结

四、在Java中操作Redis

1. Redis的Java客户端

2. Spring Data Redis使用方式

1 介绍

2 使用入门

1 导入依赖(已完成)

2 配置Redis连接信息

3 使用StringRedisTemplate操作Redis

3 操作常见类型数据

API方法:

操作字符串

操作hash

操作list

操作set

操作zset

通用操作

五、店铺营业状态设置

1. 需求分析和设计

1 产品原型

2 接口设计

3 营业状态存储方式

2. 代码开发

1 常量类BusinessStatusConstant

2 管理端-设置营业状态

2 管理端-查询营业状态

3 用户端-查询营业状态

3. 功能测试

1 接口文档测试

2 接口分组展示

3 前后端联调测试


一、Redis入门

1. Redis简介

1 NoSQL介绍

NoSql(Not Only SQL),不仅仅是SQL,泛指非关系型数据库。NoSql数据库并不是要取代关系型数据库,而是关系型数据库的补充。

关系型数据库(RDBMS): Relational Database Management System。全都是以的形式存储数据,以约束维护数据关系,有事务

  • 数据、操作都非常的严谨,不容易出错

  • 三高问题:

    高并发问题:关系型数据库如果要提供高并发的能力,需要的代价比较大。

    高性能问题:快速从海量数据里找到并操作某些数据,成本高昂

    高扩展性问题:集群+分布式,数据库增加、减少节点,或者做数据的迁移 都非常麻烦

  • 比如:Mysql,Oracle,DB2,SQLServer

非关系型数据库(NoSql):泛指一切不以表形式存储数据、不使用约束维护关系的数据库

  • 特点:更大的优势是在于“灵活”,而不是“严谨”

    • 存储数据的模式非常灵活。不以表的形式存储,以什么形式存储的?有各种各样不同的数据库,采用不同的存储形式

    • 扩展性和操作性能非常好。这些数据库都是在 大数据量、高并发的情况下,逐渐产生的一些解决方案数据库

    • 非关系型数据库,通常缺乏有效的事务管控。

  • 例如:

    • Redis:键值对结构的数据库。可以把Redis看成一个超级大的独立的HashMap。性能极强

    • MongoDB:文档型数据库。每一条数据存储成一个json对象

    • HBase:列式数据库。可以很方便的存储海量的数据

    • Neo4J:图数据库。更适合于维护拓扑结构的关系,比如社交关系

2 Redis简介

官网:Redis中文网:Redis中文网

Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,而且为了进一步提升性能,Redis把数据存储到内存里,所以它有极高的读写性能。

官方提供的数据是可以达到100000+的QPS(每秒内查询次数),是互联网技术领域使用最为广泛的存储中间件。它存储的value类型比较丰富,是NoSql数据库的一种。

主要特点:

  • 基于内存存储,读写性能高

  • 适合存储热点数据(热点商品、资讯、新闻)

  • 企业应用广泛

2. Redis下载与安装

1 Redis下载

Redis安装包分为windows版和Linux版:

资料中已提供好的安装包:

2 Redis安装

1)在Windows中安装Redis(项目中使用)

Redis的Windows版属于绿色软件,直接解压即可使用,解压后目录结构如下:

2)在Linux中安装Redis(简单了解)

在Linux系统安装Redis步骤:

  1. 将Redis安装包上传到Linux

  2. 解压安装包,命令:tar -zxvf redis-4.0.0.tar.gz -C /usr/local

  3. 安装Redis的依赖环境gcc,命令:yum install gcc-c++

  4. 进入/usr/local/redis-4.0.0,进行编译,命令:make

  5. 进入redis的src目录进行安装,命令:make install

安装后重点文件说明:

  • /usr/local/redis-4.0.0/src/redis-server:Redis服务启动脚本

  • /usr/local/redis-4.0.0/src/redis-cli:Redis客户端脚本

  • /usr/local/redis-4.0.0/redis.conf:Redis配置文件

3. Redis服务启动与停止

以window版Redis进行演示:

1 服务启动命令

  • 如果要使用默认配置启动:直接双击 redis-server.exe

  • 如果要加载配置文件启动:在cmd里

    1. 切换到redis的目录里 cd /d Redis文件夹的路径

    2. 执行命令 redis-server.exe redis.windows.conf

Redis服务默认端口号为 6379 ,通过快捷键Ctrl + C 即可停止Redis服务

当Redis服务启动成功后,可通过客户端进行连接。

2 客户端连接命令

  • 如果要连接本机6379端口的redis:直接双击redis-cli.exe

  • 如果要连接非本机或非6379端口的Redis:在cmd里

    1. 切换到Redis的目录里 cd /d Redis文件夹的路径

    2. 执行命令 redis-cli.exe -h ip地址 -p 端口号 -a 密码

3 修改Redis配置文件

设置Redis服务密码,修改redis.windows.conf

requirepass 123456

注意:

  • 修改密码后需要重启Redis服务才能生效

  • Redis配置文件中 # 表示注释

重启Redis后,再次连接Redis时,需加上密码,否则连接失败。

3 修改Redis配置文件

设置Redis服务密码,修改redis.windows.conf

requirepass 123456

注意:

  • 修改密码后需要重启Redis服务才能生效

  • Redis配置文件中 # 表示注释

重启Redis后,再次连接Redis时,需加上密码,否则连接失败。

redis-cli.exe -h localhost -p 6379 -a 123456

此时,-h 和 -p 参数可省略不写。

4 Redis客户端图形工具

默认提供的客户端连接工具界面不太友好,同时操作也较为麻烦,接下来,引入一个Redis客户端图形工具。

上面的压缩包资源,审核中

新建连接

连接成功

二、Redis数据类型【面试题】

1. 五种常用数据类型介绍

Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型:

  • 字符串 string

  • 哈希 hash

  • 列表 list

  • 集合 set

  • 有序集合 sorted set / zset

2. 各种数据类型特点

  • 字符串(string):普通字符串,Redis中最简单的数据类型

  • 哈希(hash):也叫散列,类似于Java中的HashMap结构

  • 列表(list):按照插入顺序排序,可以有重复元素,类似于Java中的LinkedList

  • 集合(set):无序集合,没有重复元素,类似于Java中的HashSet

  • 有序集合(sorted set/zset):集合中每个元素关联一个分数(score),根据分数升序排序,没有重复元素

3.Redis的数据类型及应用场景

Redis支持五种主要的数据类型:字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。每种数据类型都有其特定的使用场景,如下所示:

  1. 字符串:通常用于存储不需要频繁变动的配置信息或标识符,如用户ID、设备标识等。

  2. 哈希:适合存储对象信息,例如用户资料、商品信息,它们可以通过key-value的形式快速访问。

  3. 列表:可以用于存储有序的元素序列,如评论列表、消息队列等。

  4. 集合:用于存储无序且唯一的元素集,常用于交集、差集运算。

  5. 有序集合:通过为每个元素关联一个分数,实现按照某种顺序遍历元素,适用于排行榜、时间轴等功能

三、Redis常用命令

更多命令可以参考:

  1. 参考Redis中文网:Redis中文网

  2. 参考Redis官网:Commands | Redis

1. 字符串操作命令

Redis 中字符串类型常用命令:

操作示例:

127.0.0.1:6379> set name robin               #存储一项数据。key是name,value是robin
OK
127.0.0.1:6379> get name                     #获取key为name的value值
"robin"
127.0.0.1:6379> del name                     #删除key为name的数据
(integer) 1
127.0.0.1:6379> get name                     #获取key为name的值,获取不到,已经被删除掉了
(nil)
127.0.0.1:6379> set verify_code 123456       #设置一项数据,key是verify_code,值是123456
OK
127.0.0.1:6379> get verify_code              #获取key为verify_code的值
"123456"
127.0.0.1:6379> setnx verify_code 11111      #setnx设置verify_code的值,因为这个key已经存在,所以设置不成功
(integer) 0
127.0.0.1:6379> get verify_code              #重新获取verify_code的值,并没有被修改成11111
"123456"
127.0.0.1:6379> set verify_code 22222        #set设置verify_code的值,会把对应的值给覆盖掉
OK
127.0.0.1:6379> get verify_code              #重新获取verify_code的值,得到修改后的22222
"22222"
127.0.0.1:6379> setex code 10 abcde          #设置一个key为code,值为abcde,并且指定它的有效期为10s(10s后自动消失)
OK
127.0.0.1:6379> get code                    #还不到10s,可以获取到
"abcde"
127.0.0.1:6379> get code                    #还不到10s,可以获取到
"abcde"
127.0.0.1:6379> get code                    #到10s了,数据已经没有了
(nil)
127.0.0.1:6379>

2. 哈希操作命令

Redis hash 是一个string类型的 field 和 value 的映射表,hash特别适合用于存储对象,常用命令:

127.0.0.1:6379> hset user_1 name chenjinlong    #向key为user_1的小hash里,存储了name--chenjinlong键值对
(integer) 1
127.0.0.1:6379> hset user_1 age 23              #向key为user_1的小hash里,存储了age--23键值对
(integer) 1
127.0.0.1:6379> hset user_1 gender girl         #向key为user_1的小hash里,存储了gender-girl键值对
(integer) 1
127.0.0.1:6379> hget user_1 name                #从key为user_1对应的小hash里,获取name的值
"chenjinlong"
127.0.0.1:6379> hdel user_1 name                #从key为user_1对应的小hash里,删除name
(integer) 1
127.0.0.1:6379> hget user_1 name                #从key为user_1对应的小hash里,重新获取name的值,已经没有了
(nil)
127.0.0.1:6379> hkeys user_1                    #从key为user_1对应的小hash里,获取所有的field
1) "age"
2) "gender"
127.0.0.1:6379> hvals user_1                    #从key为user_1对应的小hash里,获取所有的value
1) "23"
2) "girl"
127.0.0.1:6379> hgetall user_1                  #从key为user_1对应的小hash里,获取所有的field-value键值对
1) "age"
2) "23"
3) "gender"
4) "girl"
127.0.0.1:6379> hlen user_1                     #从key为user_1对应的小hash里,获取小hash的长度
(integer) 2
127.0.0.1:6379>

3. 列表操作命令

Redis 列表是简单的字符串列表,按照插入顺序排序,常用命令:

127.0.0.1:6379> lpush mylist msg1 msg2 msg3 msg4  #向mylist对应的列表里,从左边依次添加msg1,msg2,msg3,msg4
(integer) 4
127.0.0.1:6379> lrange mylist 0 3                 #从mylist对应的列表里,查询索引0到索引3的数据(包含头和尾)
1) "msg4"
2) "msg3"
3) "msg2"
4) "msg1"
127.0.0.1:6379> llen mylist                         #从mylist对应的列表里,查询列表的长度
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1               #从mylist对应的列表里,查询索引0到 倒数第1个值(查询全部)
1) "msg4"
2) "msg3"
3) "msg2"
4) "msg1"
127.0.0.1:6379> lrange mylist 0 -2               #从mylist对应的列表里,查询索引0到 倒数第2个值
1) "msg4"
2) "msg3"
3) "msg2"
127.0.0.1:6379> rpop mylist                      #从mylist对应的列表里,弹出最右边的值
"msg1"
127.0.0.1:6379> rpop mylist                      #从mylist对应的列表里,弹出最右边的值
"msg2"
127.0.0.1:6379> rpop mylist                      #从mylist对应的列表里,弹出最右边的值
"msg3"
127.0.0.1:6379> rpop mylist                      #从mylist对应的列表里,弹出最右边的值
"msg4"
127.0.0.1:6379> rpop mylist                      #从mylist对应的列表里,弹出最右边的值。已经全部弹出,队列里空了
(nil)
127.0.0.1:6379> brpop mylist 5                   #从mylist对应的列表里,弹出最右边的值。如果没有值,就等待5s
(nil)
(5.06s)

4. 集合操作命令

Redis set 是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,常用命令:

127.0.0.1:6379> sadd myset chenjinlong yangchenchen jiangtao yaoyuanyuan liuchaoze #向myset对应的集合里添加多个成员
(integer) 5
127.0.0.1:6379> smembers myset         #查询myset对应的set集合里,所有的成员
1) "chenjinlong"
2) "jiangtao"
3) "yaoyuanyuan"
4) "yangchenchen"
5) "liuchaoze"
127.0.0.1:6379> srandmember myset     #从myset对应的set集合里,随机获取一个
"yangchenchen"
127.0.0.1:6379> srandmember myset     #从myset对应的set集合里,随机获取一个
"yangchenchen"
127.0.0.1:6379> scard myset           #查询myset对应的set集合里,成员的个数
(integer) 5
127.0.0.1:6379> srem myset jiangtao   #从myset对应的set集合里,移除掉一个成员jiangtao
(integer) 1
127.0.0.1:6379> smembers myset        #重新查询成员,已经少了一个
1) "liuchaoze"
2) "yangchenchen"
3) "chenjinlong"
4) "yaoyuanyuan"
127.0.0.1:6379>
127.0.0.1:6379> sadd myset1 tom jerry jack rose   #演示集合运算,准备第1个set集合
(integer) 4
127.0.0.1:6379> sadd myset2 tom jerry robin pony  #演示集合运算,准备第2个set集合
(integer) 4
127.0.0.1:6379> sinter myset1 myset2              #计算两个set集合的交集(你有我也有的)
1) "tom"
2) "jerry"
127.0.0.1:6379> sunion myset1 myset2              #计算两个set集合的并集(大家全加起来)
1) "rose"
2) "pony"
3) "jerry"
4) "tom"
5) "jack"
6) "robin"
127.0.0.1:6379> sdiff myset1 myset2              #计算两个set集合的差集:myset1 - myset2
1) "rose"
2) "jack"
127.0.0.1:6379> sdiff myset2 myset1              #计算两个set集合的差集:myset2 - myset1
1) "pony"
2) "robin"
127.0.0.1:6379>

5. 有序集合操作命令

Redis有序集合是string类型元素的集合,且不允许有重复成员。每个元素都会关联一个double类型的分数。

注意事项:

  • zset默认排序是升序的

  • 排名rank是从0开始,0表示第1名

常用命令:

127.0.0.1:6379> zadd myzset 30 zhangsan 40 lisi 50 wangwu 60 zhaoliu 70 qianqi  #向key为myzset的有序集合里添加成员
(integer) 5
127.0.0.1:6379> zrank myzset lisi           #从myzset里查询lisi的名次(从0开始的)
(integer) 1
127.0.0.1:6379> zrank myzset zhangsan       #从myzset里查询zhangsan的名次(从0开始的)
(integer) 0
127.0.0.1:6379> zscore myzset zhangsan      #从myzset里查询zhangsan的分值
"30"
127.0.0.1:6379> zrange myzset 0 2           #从myzset里从索引0(排名0)查询到索引2(排名2)的成员,包含头尾
1) "zhangsan"
2) "lisi"
3) "wangwu"
127.0.0.1:6379> zrange myzset 0 2 withscores #从myzset里从索引0(排名0)查询到索引2(排名2)成员及分值,包含头尾,
1) "zhangsan"
2) "30"
3) "lisi"
4) "40"
5) "wangwu"
6) "50"
127.0.0.1:6379> zrange myzset 0 -1 withscores #从myzset里从索引0(排名0)查询到索最后1个 成员及分值,包含头尾,
 1) "zhangsan"
 2) "30"
 3) "lisi"
 4) "40"
 5) "wangwu"
 6) "50"
 7) "zhaoliu"
 8) "60"
 9) "qianqi"
10) "70"
127.0.0.1:6379> zincrby myzset 100 zhangsan #给myzset里zhangsan成员的分值,增加上100
"130"
127.0.0.1:6379> zrange myzset 0 -1 withscores #查询所有成员及分值,发现zhangsan的分值和排名已经变了
 1) "lisi"
 2) "40"
 3) "wangwu"
 4) "50"
 5) "zhaoliu"
 6) "60"
 7) "qianqi"
 8) "70"
 9) "zhangsan"
10) "130"
127.0.0.1:6379> zincrby myzset -100 zhangsan  #给myzset里zhangsan成员的分值,增加上-100
"30"
127.0.0.1:6379> zrem myzset zhangsan          #从myzset里删除掉zhangsan成员
(integer) 1
127.0.0.1:6379> zrange myzset 0 -1            #再查询所有成员,发现zhangsan已经被删除掉了
1) "lisi"
2) "wangwu"
3) "zhaoliu"
4) "qianqi"
127.0.0.1:6379>

6. 通用命令

Redis的通用命令是不分数据类型的,都可以使用的命令:

127.0.0.1:6379> keys *         #查询当前Redis实例里的所有的key
1) "myset"
2) "myset1"
3) "verify_code"
4) "myzset"
5) "user_1"
6) "myset2"
127.0.0.1:6379> keys my*       #查询当前Redis实例里以my开头的key
1) "myset"
2) "myset1"
3) "myzset"
4) "myset2"
127.0.0.1:6379> keys myset?    #查询 myzset + 一个任意字符的key
1) "myset1"
2) "myset2"
127.0.0.1:6379> exists myzset  #判断myzset这个key是否存在
(integer) 1
127.0.0.1:6379> exists xxx     #判断xxx这个key是否存在
(integer) 0
127.0.0.1:6379> type myset     #判断myset的类型
set
127.0.0.1:6379> type myzset    #判断myzset的类型
zset
127.0.0.1:6379> del myzset     #删除key为myzset的数据
(integer) 1
127.0.0.1:6379> keys *         #删除之后再查询,已经没有myzset了
1) "myset"
2) "myset1"
3) "verify_code"
4) "user_1"
5) "myset2"
127.0.0.1:6379>

7. 小结

key的类型:字符串或字节数组
value的类型:常用的有
    string:短信验证码
        存:set key value
        取:get key
        删:del key
    hash:存储一组相关的数据,比如购物车
        存:hset key field value
        取:hget key field
        删:hdel key field
    list:用于排队场景
        存:lpush key value1 value2 ....    从左边添加到列表里
        取:rpop key                        从右边弹出最边缘的这个元素值
    set:用于不分名次的一批数据存储,比如 点赞人
        存:sadd key value1 value2 ....     
        取:srandmember key              从key对应的set里,随机取一个
        删:srem key value1 value2 ....
    zset:用于排行榜
        存:zadd key score1 value1 score2 value2 ...
        取:
            取某成员的rank名次:zrank key value
            取某成员的score值: zscore key value
            按名次范围取成员:   zrange key 开始索引 结束索引 withscores
        删:zrem key value1 value2...

四、在Java中操作Redis

1. Redis的Java客户端

前面我们讲解了Redis的常用命令,这些命令是我们操作Redis的基础,那么我们在java程序中应该如何操作Redis呢?这就需要使用Redis的Java客户端,就如同我们使用JDBC操作MySQL数据库一样。

Redis 的 Java 客户端很多,常用的几种:

  • Jedis

  • Lettuce

  • Spring Data Redis

Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis。

我们重点学习Spring Data Redis

2. Spring Data Redis使用方式

1 介绍

Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。

网址:Spring Data Redis

Spring Boot提供了对应的Starter,maven坐标:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Spring Data Redis中提供了 用于操作redis的高度封装的类:

  • RedisTemplate:操作Redis的模板类,它提供了操作Redis的一系列方法。

  • StringRedisTemplate:是RedisTemplate的子类,采用String序列化方式

对相关api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

  • ValueOperations:string数据操作

  • SetOperations:set类型数据操作

  • ZSetOperations:zset类型数据操作

  • HashOperations:hash类型的数据操作

  • ListOperations:list类型的数据操作

2 使用入门

进入到sky-server模块

1 导入依赖(已完成)

导入Spring Data Redis的maven坐标

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2 配置Redis连接信息

简单配置,直接在application.yml里配置如下:

spring:
  redis:
    host: localhost
    port: 6379
    #password:
    database: 0 #一个Redis服务默认有16个database子库,我们默认使用的是0号库

了解苍穹里项目的配置,简单了解就行了。按照上边的配置完全是可以的,不必下面这样复杂配置

在application-dev.yml中配置Redis数据源:

sky:
redis:
 host: localhost
 port: 6379
 password: 123456
 database: 10

解释说明:

database:指定使用Redis的哪个数据库,Redis服务启动后默认有16个数据库,编号分别是从0到15。

可以通过修改Redis配置文件来指定数据库的数量。

在application.yml中添加读取application-dev.yml中的相关Redis配置

spring:
profiles:
 active: dev
redis:
 host: ${sky.redis.host}
 port: ${sky.redis.port}
 password: ${sky.redis.password}
 database: ${sky.redis.database}

3 使用StringRedisTemplate操作Redis

在test下新建测试类

package com.sky.test;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;

@SpringBootTest
public class SpringDataRedisTest {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Test
    public void testRedisTemplate(){
        System.out.println(redisTemplate);
        //string数据操作
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //hash类型的数据操作
        HashOperations hashOperations = redisTemplate.opsForHash();
        //list类型的数据操作
        ListOperations listOperations = redisTemplate.opsForList();
        //set类型数据操作
        SetOperations setOperations = redisTemplate.opsForSet();
        //zset类型数据操作
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
    }
}

如果能打印成功,说明RedisTemplate对象注入成功,并且通过该RedisTemplate对象获取操作5种数据类型相关对象。

3 操作常见类型数据

API方法:

StringRedisTemplate对象提供的常用方法:

通用操作:

  • delete(String key):删除key

操作字符串:

  • opsForValue().set(String key, String value):存储一个键值对。相当于命令 set key value

  • opsForValue().setIfAbsent(String key, String value):存储一个键值对。

    如果key不存在,会存储成功;否则会存储失败

    返回值:Boolean,true表示存储成功了,false表示存储失败了

  • opsForValue().get(String key):获取key对应的值。相当于命令 get key

操作hash:

  • 存:opsForHash().put(String key, String field, String value)

  • 取:opsForHash().get(String key, String field)

  • 删:opsForHash().delete(String key, String field)

操作list:

  • 存:

    • opsForList().leftPush(String key, String value)

    • opsForList().leftPushAll(String key, String... value)

  • 取:opsForList().rightPop(String key)

操作set:

  • 存:opsForSet().add(String key, String... value)

  • 取:

    • 取所有成员:opsForSet().members(String key)

    • 随机取成员:opsForSet().randomMember(String key)

  • 删:opsForSet().remove(String key, String... value)

操作zset:

  • 存:opsForZSet().add(String key, String value, double score)

  • 取:

    • 取某成员的名次:opsForZSet().rank(String key, String value)

    • 取某成员的分值:opsForZSet().score(String key, String value)

    • 按名次范围查询:opsForZSet().range(String key, long start, long stop)

  • 删:opsForZSet().remove(String key, String... value)

操作字符串
	/**
     * 操作字符串类型的数据
     */
    @Test
    public void testString(){
        // set get setex setnx
        redisTemplate.opsForValue().set("name","小明");
        String city = (String) redisTemplate.opsForValue().get("name");
        System.out.println(city);
        redisTemplate.opsForValue().set("code","1234",3, TimeUnit.MINUTES);
        redisTemplate.opsForValue().setIfAbsent("lock","1");
        redisTemplate.opsForValue().setIfAbsent("lock","2");
    }
操作hash
/**
     * 操作哈希类型的数据
     */
    @Test
    public void testHash(){
        //hset hget hdel hkeys hvals
        HashOperations hashOperations = redisTemplate.opsForHash();

        hashOperations.put("100","name","tom");
        hashOperations.put("100","age","20");

        String name = (String) hashOperations.get("100", "name");
        System.out.println(name);

        Set keys = hashOperations.keys("100");
        System.out.println(keys);

        List values = hashOperations.values("100");
        System.out.println(values);

        hashOperations.delete("100","age");
    }
操作list
/**
     * 操作列表类型的数据
     */
    @Test
    public void testList(){
        //lpush lrange rpop llen
        ListOperations listOperations = redisTemplate.opsForList();

        listOperations.leftPushAll("mylist","a","b","c");
        listOperations.leftPush("mylist","d");

        List mylist = listOperations.range("mylist", 0, -1);
        System.out.println(mylist);

        listOperations.rightPop("mylist");

        Long size = listOperations.size("mylist");
        System.out.println(size);
    }
操作set
/**
     * 操作集合类型的数据
     */
    @Test
    public void testSet(){
        //sadd smembers scard sinter sunion srem
        SetOperations setOperations = redisTemplate.opsForSet();

        setOperations.add("set1","a","b","c","d");
        setOperations.add("set2","a","b","x","y");

        Set members = setOperations.members("set1");
        System.out.println(members);

        Long size = setOperations.size("set1");
        System.out.println(size);

        Set intersect = setOperations.intersect("set1", "set2");
        System.out.println(intersect);

        Set union = setOperations.union("set1", "set2");
        System.out.println(union);

        setOperations.remove("set1","a","b");
    }
操作zset
/**
     * 操作有序集合类型的数据
     */
    @Test
    public void testZset(){
        //zadd zrange zincrby zrem
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();

        zSetOperations.add("zset1","a",10);
        zSetOperations.add("zset1","b",12);
        zSetOperations.add("zset1","c",9);

        Set zset1 = zSetOperations.range("zset1", 0, -1);
        System.out.println(zset1);

        zSetOperations.incrementScore("zset1","c",10);

        zSetOperations.remove("zset1","a","b");
    }
通用操作
/**
     * 通用命令操作
     */
    @Test
    public void testCommon(){
        //keys exists type del
        Set keys = redisTemplate.keys("*");
        System.out.println(keys);

        Boolean name = redisTemplate.hasKey("name");
        Boolean set1 = redisTemplate.hasKey("set1");

        for (Object key : keys) {
            DataType type = redisTemplate.type(key);
            System.out.println(type.name());
        }

        redisTemplate.delete("mylist");
    }

五、店铺营业状态设置

1. 需求分析和设计

1 产品原型

进到苍穹外卖后台,显示餐厅的营业状态,营业状态分为营业中打烊中,若当前餐厅处于营业状态,自动接收任何订单,客户可在小程序进行下单操作;若当前餐厅处于打烊状态,不接受任何订单,客户便无法在小程序进行下单操作。

点击营业状态按钮时,弹出更改营业状态

2 接口设计

根据上述原型图设计接口,共包含3个接口。

接口设计:

  • 设置营业状态

  • 管理端查询营业状态

  • 用户端查询营业状态

注:从技术层面分析,其实管理端和用户端查询营业状态时,可通过一个接口去实现即可。因为营业状态是一致的。但是,本项目约定:

  • 管理端发出的请求,统一使用/admin作为前缀。

  • 用户端发出的请求,统一使用/user作为前缀。

因为访问路径不一致,故分为两个接口实现。

1). 设置营业状态

2). 管理端营业状态

3). 用户端营业状态

3 营业状态存储方式

虽然,可以通过一张表来存储营业状态数据,但整个表中只有一个字段,所以意义不大。

营业状态数据存储方式:基于Redis的字符串来进行存储

2. 代码开发

1 常量类BusinessStatusConstant

准备一个常量类,用于存储 营业状态缓存的key

package com.sky.constant;

public interface BusinessStatusConstant {
    /**营业状态缓存的key*/
    String BUSINESS_STATUS_KEY = "business:key";
}

2 管理端-设置营业状态

在sky-server模块中,创建AdminShopController.java

package com.sky.controller.admin;

import com.sky.constant.BusinessStatusConstant;
import com.sky.result.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

@RestController
@Api(tags = "营业状态相关接口")
@RequestMapping("/admin/shop")
public class AdminShopController {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @PutMapping("/{status}")
    @ApiOperation("设置营业状态")
    public Result setShopStatus(@PathVariable("status") Integer status){
        redisTemplate.opsForValue().set(BusinessStatusConstant.BUSINESS_STATUS_KEY, status.toString());
        return Result.success();
    }
}

2 管理端-查询营业状态

@GetMapping("/status")
@ApiOperation("查询营业状态")
public Result queryShopStatus(){ 
    String status = redisTemplate.opsForValue().get(BusinessStatusConstant.BUSINESS_STATUS_KEY);
    return Result.success(Integer.parseInt(status));
}

3 用户端-查询营业状态

创建com.sky.controller.user包,在该包下创建ShopController.java

根据接口定义创建ShopController的getStatus查询营业状态方法:

package com.sky.controller.user;

import com.sky.constant.BusinessStatusConstant;
import com.sky.result.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Api(tags = "查询营业状态-用户端")
@RequestMapping("/user/shop")
public class UserShopController {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping("/status")
    @ApiOperation("查询营业状态")
    public Result queryShopStatus(){
        String status = redisTemplate.opsForValue().get(BusinessStatusConstant.BUSINESS_STATUS_KEY);
        if(status == null || "".equals(status)){
            return Result.success(0);
        }
        return Result.success(Integer.parseInt(status));
    }
}

3. 功能测试

1 接口文档测试

启动服务:访问http://localhost:8080/doc.html,打开店铺相关接口

注意:使用admin用户登录重新获取token,防止token失效。

设置营业状态:

管理端查询营业状态:

用户端查询营业状态:

2 接口分组展示

在上述接口文档测试中,管理端和用户端的接口放在一起,不方便区分

接下来,我们要实现管理端和用户端接口进行区分。

在WebMvcConfiguration.java中,分别扫描"com.sky.controller.admin"和"com.sky.controller.user"这两个包。

	@Bean
    public Docket docket1(){
        log.info("准备生成接口文档...");
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();

        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("管理端接口")
                .apiInfo(apiInfo)
                .select()
                //指定生成接口需要扫描的包
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin"))
                .paths(PathSelectors.any())
                .build();

        return docket;
    }

    @Bean
    public Docket docket2(){
        log.info("准备生成接口文档...");
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();

        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("用户端接口")
                .apiInfo(apiInfo)
                .select()
                //指定生成接口需要扫描的包
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller.user"))
                .paths(PathSelectors.any())
                .build();

        return docket;
    }

3 前后端联调测试

启动nginx,访问 http://localhost

  • 20
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: Redis支持的数据类型包括字符串(String)、字典(Hash)、列表(List)、集合(Set)、有序集合(SortedSet)、HyperLogLog、Geo和Pub/Sub。其字符串是最基本的数据类型, Hash用于存储键值对的集合, List是一个有序的字符串列表, Set是一个不重复的字符串集合, SortedSet是一个有序的、不重复的字符串集合。除了这些基本的数据类型,如果你是Redis的高级用户,还可能接触到HyperLogLog、Geo和Pub/Sub等高级数据结构。另外,Redis也支持集群架构,可以将多台服务器构成一个整体,对外界来说,这一组服务器就像是集群一样,可以实现横向扩展和负载均衡。 对于数据的存取,Redis使用不同的符号来标识不同的数据类型,比如" "表示简单字符串,"-"表示错误,":"表示整数,"$"表示字符串,"*"表示数组。 Redis的持久化机制非常重要,在面试也会经常被问到,你可以参考相关文章来深入理解Redis的持久化机制和架构模式。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [来讨论一下这些常见的 Redis 面试题](https://blog.csdn.net/weixin_36380516/article/details/105321477)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [46道Redis面试题,含参考答案!](https://blog.csdn.net/m0_72885838/article/details/126182169)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [redis面试题总结(附答案)](https://blog.csdn.net/guorui_java/article/details/117194603)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值