苍穹外卖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版:

  • Windows版下载地址:Releases · microsoftarchive/redis · GitHub

  • Linux版下载地址: Index of /releases/

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

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 {@Autowiredprivate StringRedisTemplate redisTemplate;@Testpublic 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)

操作字符串
	/*** 操作字符串类型的数据*/@Testpublic void testString(){// set get setex setnxredisTemplate.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
/*** 操作哈希类型的数据*/@Testpublic void testHash(){//hset hget hdel hkeys hvalsHashOperations 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
/*** 操作列表类型的数据*/@Testpublic void testList(){//lpush lrange rpop llenListOperations 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
/*** 操作集合类型的数据*/@Testpublic void testSet(){//sadd smembers scard sinter sunion sremSetOperations 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
/*** 操作有序集合类型的数据*/@Testpublic void testZset(){//zadd zrange zincrby zremZSetOperations 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");}
通用操作
/*** 通用命令操作*/@Testpublic void testCommon(){//keys exists type delSet 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 {@Autowiredprivate 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 {@Autowiredprivate 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"这两个包。

	@Beanpublic 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;}@Beanpublic 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/786297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何让光猫4个网口都有网络

一般情况光猫只有LAN1口有网络&#xff0c;LAN2、LAN3和LAN4口都是预留给电视用的&#xff0c;那么如何让这3个网口也有网络呢&#xff1f; 使用场景&#xff1a; 光猫在弱电箱内&#xff0c;弱电箱中有三根网线&#xff08;网线1、网线2和网线3&#xff09;分别接入到了三个房…

基于Arduino IDE 野火ESP8266模块 文件系统LittleFS 的开发

一、文件系统LittleFS的介绍 LittleFS是一个为微控制器设计的轻量级、可靠且高性能的文件系统。它专为嵌入式设备打造&#xff0c;拥有占用空间小、对硬件要求低的特点&#xff0c;同时保证在断电情况下数据的完整性和稳定性。 1.设计与特点 LittleFS的设计旨在提供嵌入式系统所…

依赖倒转原则

1.1 MM请求电脑 MM电脑坏了&#xff0c;需要修电脑&#xff0c;是因为每次打开QQ,一玩游戏&#xff0c;机器就死了。出来蓝底白字的一堆莫名奇妙的英文。蓝屏死机了&#xff0c;估计内存有问题。 1.2 电话遥控修电脑 遥控修理电脑&#xff0c;打开内存条&#xff0c;两根内存…

Vivado使用(6)——增量综合( Incremental Synthesis)

目录 一、概述 1.1 增量综合的工作原理 1.2 增量综合的优点 1.3 注意事项 二、设置增量综合 2.1 Write Incremental Synthesis 复选框 2.2 Incremental Synthesis 选择框 2.2.1 自动使用上一次运行的检查点&#xff08;Automatically use the checkpoint from the…

Vue(十二):脚手架配置代理,github案例,插槽

一、脚手架配置代理 老师讲的主要有两种方法&#xff1a; 但是我的没有proxy&#xff0c;只有proxyTable,之前一直不成功&#xff0c;现在我是这样配置的&#xff1a; config文件夹下的index.js: App.vue: 然后就成功了&#xff1a;&#xff08;我真服了&#xff0c;之前在这…

jdbc连SQL server,显示1433端口连接失败解决方法

Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: 通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。错误:“connect timed out。请验证连接属性。确保 SQL Server 的实例正在主机上运行&#xff0c;且在此端口接受 TCP/IP 连接…

零基础入门实战深度学习Pytorch课程下载

本课程旨在帮助零基础学员掌握PyTorch深度学习框架。通过实战项目&#xff0c;学员将学习神经网络基础、模型训练和调优技巧。逐步掌握深度学习核心概念&#xff0c;为未来在人工智能领域打下坚实基础。 课程大小:2.6G 课程下载&#xff1a;https://download.csdn.net/downlo…

【战略前沿】与中国达成生产协议后,飞行汽车即将起飞

【原文】Flying cars edge towards takeoff after Chinese production deal 【作者】Thomas Macaulay 斯洛伐克公司KleinVision签署了一项协议&#xff0c;将大规模生产AirCar。 一辆获得航空认证的飞行汽车向商业化又迈出了一大步。 空中汽车的创造者KleinVision今天宣布出售…

【经验分享】Ubuntu下如何解决问题arm-linux-gcc:未找到命令

【经验分享】Ubuntu下如何解决问题arm-linux-gcc&#xff1a;未找到命令 前言问题分析解决方法 前言 在编译过程中发现一个问题&#xff0c;明明之前安装了gcc-4.6版本&#xff0c;版本信息都是正常显示的&#xff0c;刚安装上去的时候也是可以用的。但不知道什么原因突然不能…

HUAWEI 华为交换机 配置 Eth-Trunk 接口流量本地优先转发示例(堆叠)

组网需求 说明 S5720I-10X-PWH-SI-AC 和 S5720I-6X-PWH-SI-AC 不支持此配置。 如 图 3-23 所示&#xff0c;为了增加设备的容量采用设备堆叠技术&#xff0c;将 Switch3 和 Switch4通过专用的堆叠电缆链接起来&#xff0c;对外呈现为一台逻辑交换机。为了实现设备间的备份、…

Windows基线安全检测-安全配置检测

Windows基线安全检测-安全配置检测 前言 Windows在生产环境中是使用最多的一个系统&#xff0c;大部分为客户端&#xff0c;少部分为服务端&#xff1b; 然而其实很多用户对windows系统不是很了解&#xff0c;安全配置更是如此&#xff1b; 因此我们安全人员要定期对员工的主…

中科驭数DPU技术开放日秀“肌肉”:云原生网络、RDMA、安全加速、低延时网络等方案组团亮相

2024年3月29日&#xff0c;中科驭数以“DPU构建高性能云算力底座”为主题的线上技术开放日活动成功举办。在开放日上&#xff0c;中科驭数集中展现了其在低时延网络、云原生网络及智算中心网络三大关键场景下的技术成果与五大核心DPU解决方案&#xff0c;凸显了中科驭数在高性能…

RabbitMQ安装及Springboot 集成RabbitMQ实现消息过期发送到死信队列

死信队列 RabbitMQ 的死信队列&#xff08;Dead-Letter-Exchanges&#xff0c;简称 DLX&#xff09;是一个强大的特性&#xff0c;它允许在消息在队列中无法被正常消费&#xff08;例如&#xff0c;消息被拒绝并且没有设置重新入队&#xff0c;或者消息过期&#xff09;时&…

1236. 递增三元组:做题笔记

目录 暴力 代码 二分 代码 前缀和 代码 推荐视频讲解 暴力 这道题说的是有三个元素数量相同的数组&#xff0c;想知道有多少个三元组满足&#xff1a;三个数分别来自 A B C数组且呈现递增。 我想的是既然要求递增&#xff0c;那就先把数组数据都排一下序&#xff0c;…

springCloudAlibaba集成gateWay实战(详解)

一、初识网关&#xff1f; 1、网关介绍 ​ 在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f;如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别去调用。这样的话…

【opencv】教程代码 —features2D(8)AKAZE 特征点匹配和图像拼接

graf1.png graf3.png <?xml version"1.0"?> <opencv_storage> <H13 type_id"opencv-matrix"><rows>3</rows><cols>3</cols><dt>d</dt><data>7.6285898e-01 -2.9922929e-01 2.2567123e02…

matlab碰撞检测

文章目录 碰撞对象collisionCylindercollisionBoxcollisionMeshcollisionSpherecollisionCapsulecheckCollisionfitCollisionCapsuleshowCollisionArraycapsuleApproximationaddCapsuleremoveCapsuleconvertToCollisionMesh碰撞对象 函数功能checkCollision检测两几何体是否存在…

前端之CSS——网页的皮肤!!

目录 一、CSS简单介绍 二、css内容 2.1 css的编写方式 2.2 css选择器 2.3 样式属性 2.4 css包围盒 2.5 css中的display 2.6 css中的定位 2.7 css中的浮动与清除 2.7 弹性容器 2.8 字体图标 2.9 …

1.5编写一个程序,输入梯形的上底,下底和高,输出梯形的面积。

1、编写一个程序,输入梯形的上底,下底和高,输出梯形的面积。 package com.kangning.web.controller.system;import java.util.Scanner;/*** 编写一个程序,输入梯形的上底,下底和高,输出梯形的面积。*/ public class CountArea {public static void main(String[] args) …

面向对象编程中的StringBuffer类详解

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…