Redis快速入门店铺营业状态设置

Redis简介

        Redis是一种基于内存的键值对(K-V)数据库。
        这意味着它与MySQL数据库类似,都能够用于存储数据,但两者又有着本质的区别。首先两者存储数据的结构不一样,Redis通过键(key)和值(value)的映射来存储信息,其中键是唯一的标识,而值可以是灵活多样的数据结构,如字符串、列表、集合等。MySQL则采用二维表的结构来组织数据,这种结构更适合复杂的关系型数据存储。
        其次两者的存储介质不同,Redis将其数据存储在内存中,这种内存存储机制使得Redis在数据读写操作上远超基于磁盘存储的MySQL。而MySQL则将数据以文件形式存储在硬盘上,虽然这为数据持久化提供了保障,但在性能上自然无法与内存中的Redis相提并论。

        简而言之,Redis的内存存储与MySQL的磁盘存储,分别代表了性能与持久性的两种不同选择。因此两者虽都是数据库,但并不意味着能取代对方,两者互相搭配使用才合适。由于Redis存储在内存中,所以能够提供极快的访问速度,读写性能较高,但又因为内存的空间较为宝贵,所以只适合存储一些访问频率较高的数据。

Redis官网icon-default.png?t=O83Ahttps://redis.ioRedis中文网icon-default.png?t=O83Ahttps://www.redis.net.cn/

下载与安装

        下载Redis的Windows版,该版本属于绿色软件,直接解压就可使用,解压后有几个比较重要的文件:

  • redis.windows.conf:Redis配置文件—修改端口、密码等
  • redis-cli.exe:Redis客户端—连接到Redis服务
  • redis-server.exe:Redis服务端—服务端启动命令

        我们先来介绍如何通过CMD窗口操作Redis(仅供了解)

        通过CMD窗口启动须在当前目录的路径框中输入cmd:

        然后输入"redis-server.exe redis.windows.conf"(注意中间有一个空格) 显示对应页面即为启动成功,页面显示其默认端口号为6379:

        停止该服务在CDM窗口按下ctrl+c即可。我们在服务开启的前提下再使用同样的方法打开一个新的CMD窗口,然后输入redis-cli.exe客户端即可连接到本地的Redis服务器。我们也可以输入key *来验证是否连接成功:

        此时就已连接到了本地的服务器,连接外部的服务器也大差不差,我们先输入exit退出当前连接,然后输入"redis-cli -h 主机地址 -p 端口号 -a 密码"即可,我们可以使用本地服务器代替:redis-cli -h localhost -p 6379,同样可以输入key *来验证是否连接成功。

        可以注意到此时本地的redis服务器并无密码,我们可以先停止redis服务,然后到redis.windows.conf文件中搜索requirepass,修改"# requirepass foobared"为"requirepass 密码",保存即可(学习时推荐使用123456)。

        接下来下载Redis 可视化工具:Another Redis Desktop Manager github

        该可视化工具为免费的开源项目,页面非常简洁美观,基本的功能都有,支持多平台、监控统计、页面主题、集群、搜索,分组显示,多选操作。下面是Github和Gitee的下载网址

https://github.com/qishibo/AnotherRedisDesktopManager/releasesicon-default.png?t=O83Ahttp://xn--github-np7ii83deeq211d

https://gitee.com/qishibo/AnotherRedisDesktopManager/releasesicon-default.png?t=O83Ahttp://xn--gitee-gi1hh06cxd9647c        启动后输入相关信息,在启动Redis数据库的前提下,页面显示如下即为连接成功:

Redis数据类型

        上文介绍过Redis通过键(key)和值(value)的映射来存储信息,其中键(key)为string类型,值(value)则有5种常用的数据类型,分别是:

一、字符串string
        普通字符串,Redis中最简单的数据类型。它可以包含任何数据,如文本、数字或图片等。

二、哈希hash
        也叫散列,类似于java中的HashMap结构。
        注意是在value中存储K-V的数据,整体结构为K-(K-V)。例如key为user,value为(name=aaa,password=aaa......)。

三、列表list
        按照插入的顺序排序,可以有重复元素,类似于java中的LinkedList(双向链表)。

四、集合set
        无序集合,没有重复元素,类似于java中的HashSet,常用于好友列表。

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

Redis常用命令

        我们可以通过这些命令来操作Redis中的数据。但其与MySQL中操作数据不同,操作Redis需要根据数据类型的不同执行不同的命令,同时Redis和MySQL一样是不区分大小写的。接下来我们来看五种类型的常用命令:

一、字符串操作命令

  • SET key value:设置指定key的值
  • GET key:获取指定key的值
  • SETEX key seconds value:设置指定key的值,并将key的过期时间设为seconds秒
  • SETNX key value:只有在key不存在时设置key的值

        接下来我们来练习如何使用这些命令,打开刚刚已配置好的图形界面,点击左上角的打开Redis控制台,即可在右下方的输入框输入命令set name jack并回车,上方就会显示已执行过的命令与"OK"字样,左侧显示已存在的Key的值,点击该Key即可在右侧新标签页查看Value的信息,包括类型、值等。

> test connected!  # 测试连接成功
> set name jack    # 设置键"name"的值为"jack"
OK
> get name         # 获取键"name"的值
jack
> get aaa          # 尝试获取不存在的键"aaa",返回null
null
> SETEX code 30 mycode  # 设置键"code"的值为"mycode",并设置过期时间为30秒
OK
> get code         # 获取键"code"的值,此时还未过期
mycode
> get code         # 再次获取键"code"的值,此时可能已经过期,返回null
null
> SETNX name aaaa  # 尝试设置键"name"的值为"aaaa",如果"name"已存在则不设置,返回0表示失败
0
> SETNX name1 aaaa # 尝试设置键"name1"的值为"aaaa",因为"name1"不存在,设置成功,返回1
1

         如果添加的key在左侧不显示,可以点击控制台旁边的刷新按钮即可。在value值标签页中,包含了key的值、value的类型、value的值、value的过期时间等信息。

 

二、哈希操作命令

        Redis hash 是一个 string 类型的 field 和 value 的映射表, hash 特别适合用于存储对象, 整体结构为K-(K-V):

        常用命令:

  • HSET key field aaaa:将哈希表 key 中的字段 field 的值设置为指定的值
  • HGET key field:获取存储在哈希表中指定字段的值
  • HDEL key field:删除存储在哈希表中的指定字段
  • HKEYS key:获取哈希表中所有字段
  • HVALS key:获取哈希表中所有值
> hset user name jack # 在哈希表"user"中设置字段"name"的值为"jack",如果字段不存在则创建,返回1表示成功
1
> hset user age 22 # 在哈希表"user"中设置字段"age"的值为"22",如果字段不存在则创建,返回1表示成功
1
> hget user name # 获取哈希表"user"中字段"name"的值
jack
> hdel user age # 删除哈希表"user"中的字段"age",如果字段存在则删除,返回1表示成功
1
> hset user age 22 # 再次在哈希表"user"中设置字段"age"的值为"22",因为字段已被删除,这里重新创建字段
1
> hkeys user # 获取哈希表"user"中所有的字段名
name
age
> hvals user # 获取哈希表"user"中所有的字段值
jack
22

三、列表操作命令

        Redis列表是简单的字符串列表,按照插入顺序排序,基本结构为:

        列表操作命令大多分类R和L两个版本,R意为right,L意为left。为这些数据生成的索引也是从0开始的。常用命令:

  • LPUSH key value1 [value2]:将一个或多个值插入到列表头部([]意为可选),多个元素直接以空格分开。其结构类似于栈,先插入的在尾部
  • LRANGE key start stop:获取列表指定范围内的元素,start和stop均为value的索引,后插入的value索引值小。
  • RPOP key:移除并获取列表最后一个元素
  • LLEN key 获取列表长度
> lpush mylist a b c  # 将字符串 'a', 'b', 'c' 依次推入列表 mylist 的头部,返回列表的长度,此时列表为 [c, b, a]
3                       # 列表操作后长度为 3
> lpush mylist d       # 将字符串 'd' 推入列表 mylist 的头部,返回列表的长度,此时列表为 [d, c, b, a]
4                       # 列表操作后长度为 4
> lrange mylist 0 -1   # 获取列表 mylist 从索引 0 到最后一个元素(-1 表示最后一个元素),即获取整个列表
d
c
b
a                      # 列表元素依次为 'd', 'c', 'b', 'a'
> lrange mylist 1 3    # 获取列表 mylist 从索引 1 到索引 3 的元素,但不包括索引 3 的元素
c
b
a                      # 列表元素依次为 'c', 'b', 'a'
> rpop mylist          # 移除列表 mylist 的最后一个元素,并返回该元素的值,此时列表最后一个元素 'a' 被移除
a                      # 移除的元素是 'a'
> llen mylist          # 获取列表 mylist 的长度
3                      # 列表操作后长度为 3,此时列表为 [d, c, b]

四、集合操作命令

        Redis set 是string类型的无序集合。 集合成员是唯一的, 集合中不能出现重复的数据。因为其是无序的,所以实际存储顺序可能和插入顺序不一致。常用命令:

  • SADD key member1 [member2]:向集合添加一个或多个成员
  • SMEMBERS key:返回集合中的所有成员,
  • SCARD key:获取集合的成员数
  • SINTER key1 [key2]:返回给定所有集合的交集
  • SUNION key1 [key2]:返回所有给定集合的并集
  • SREM key member1 [member2]:删除集合中的一个或多个成员
# 向集合 setkey 添加元素 'a', 'b', 'c', 'd',并返回成功添加的元素数量
sadd setkey a b c d
4 # 表示有4个元素被成功添加到集合中
# 尝试再次向集合 setkey 添加元素 'a',但由于 'a' 已存在,不会重复添加,返回0
sadd setkey a
0 # 表示没有元素被添加,因为 'a' 已经在集合中
# 获取并显示集合 setkey 中的所有成员
smembers setkey
c
b
d
a # 显示集合中的所有元素,注意集合是无序的
# 获取集合 setkey 的基数,即集合中元素的数量
SCARD setkey
4 # 集合 setkey 中有4个元素
# 向集合 setkey2 添加元素 'a', 'b', 'x', 'y',并返回成功添加的元素数量
sadd setkey2 a b x y
4 # 表示有4个元素被成功添加到集合 setkey2 中
# 获取集合 setkey 和 setkey2 的交集,即两个集合共有的元素
sinter setkey setkey2
b
a # 显示集合 setkey 和 setkey2 的交集元素
# 获取集合 setkey 和 setkey2 的并集,即两个集合中所有的元素,重复的只计算一次
sunion setkey setkey2
c
x
a
d
b
y # 显示集合 setkey 和 setkey2 的并集元素
# 从集合 setkey2 中移除元素 'a',并返回成功移除的元素数量
srem setkey2 a
1 # 表示成功移除了1个元素 'a'

         实际存储顺序可能和插入顺序不一致:

五、有序集合操作命令

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

  • ZADD key score1 member1 [score2 member2]:向有序集合添加一个或多个成员
  • ZRANGE key start stop [WITHSCORES]:通过索引区间返回有序集合中指定区间的成员,添加WITHSCORES表示将分数也一起返回
  • ZINCRBY key increment member:对指定成员的分数增加increment
  • ZREM key member [member…]:移除有序集合中的一个或多个成员
# 向有序集合 zset 添加三个成员及其分数
# 成员 'a' 的分数是 10.0,成员 'b' 的分数是 10.2,成员 'c' 的分数是 10.5
# 返回值 3 表示成功添加了三个成员
ZADD zset 10.0 a 10.2 b 10.5 c
3# 获取有序集合 zset 中所有成员及其分数,从索引 0 到最后一个成员
# withscores 参数表示输出结果中包含每个成员的分数
# 输出结果按照分数从小到大排序
ZRANGE zset 0 -1 withscores
a
10
b
10.199999999999999
c
10.5# 将有序集合 zset 中成员 'a' 的分数增加 0.1
# 返回值是成员 'a' 增加后的新分数
ZINCRBY zset 0.1 a
10.1# 获取有序集合 zset 中成员 'c' 的倒序排名(从分数最高到最低)
# 返回值 0 表示 'c' 是分数最高的成员
ZREVRANK zset c
0# 从有序集合 zset 中移除成员 'c'
# 返回值 1 表示成功移除了一个成员
ZREM zset c
1

六、通用命令

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

  • KEYS pattern:查找所有符合给定模式(pattern)的key,pattern可以是"*"、""、""、""。
  • EXISTS key:检查给定key是否存在
  • TYPE key:返回key所储存的值的类型
  • DEL key:该命令用于在key存在是删除key
> keys *    # 列出所有以任意字符开头的键
zset
name1
user   
setkey2   
name   
setkey   
mylist> keys set* # 列出所有以"set"开头的键
setkey2   
setkey    > EXISTS user   # 检查键"user"是否存在,1表示存在
1> EXISTS user1  # 检查键"user1"是否存在,0表示不存在
0> TYPE mylist   # 查询键"mylist"的数据类型,返回"list"表示它是一个列表
list> DEL mylist    # 删除键"mylist"及其值,返回1表示删除成功
1

使用Redis

        通过上述的命令,我们就可以操作Redis中的数据,但最终我们需要为项目服务,也就是说需要在java程序中操作Redis。

Redis的java客户端

        Redis的java客户端有很多,常用的有

一、 Jedis
        Jedis是一个简单而强大的Java客户端,用于与Redis进行通信。它提供了完整的Redis命令的API,并支持连接池管理。Jedis使用直接连接到Redis服务器的方式,是Redis的原生Java客户端之一。

二、 Lettuce
        Lettuce是一个高性能的Redis客户端,基于Netty框架实现。它使用异步和反应式编程模型,可以更有效地利用网络资源。

三、Spring Data Redis

        Spring Data Redis是Spring的一部分,对Redis底层开发包(Jedis和Lettuce)进行了高度封装。在Spring项目中,可以使用Spring Data Redis来简化操作。

idea使用Redis准备事项

        总计需要四步

一、导入Spring Data Redis 的maven坐标

        打开idea中原有的项目,原有代码已经在server模块的pom.xml中预先添加了,我们检查是否正确即可:

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

二、配置Redis数据源

        之前在创建Redis数据库时,系统总计创建了从0-15总计16个数据库,每个数据库之间的数据都是相互隔离的,我们之前使用的都是默认的0号数据库。

        idea中同理,默认使用0号数据库,如需指定则需配置spring.redis.database:10,代表想要使用10号数据库。

        同样,我们不推荐使用硬编码的方式配置数据库信息,因此我们选择先在application-dev.yml中配置数据库信息,然后引用其信息。在server模块的application.yml和application-dev.yml中添加属性:

————application-dev.yml————————————————————————————
sky:
......redis: # Spring Boot 配置Redis属性host: localhost       # Redis服务器地址port: 6379            # Redis服务器端口password: 123456      # Redis服务器密码database: 10           # 选择哪个数据库,默认为0
————application.yml————————————————————————————————
spring:
......redis:host: ${sky.redis.host}port: ${sky.redis.port}password: ${sky.redis.password}database: ${sky.redis.database}

三、编写配置类,创建RedisTemplate对象

        在server模块的config包下新建RedisConfiguration类,并添加注解@Configuration将其作为配置类,然后新建一方法返回类型为RedisTemplate,在方法上加入注解@Bean并在该方法的参数中注入RedisConnectionFactory实例。
        再在方法体中新建RedisTemplate类的实例,编写对应代码以完成设置Redis连接工厂对象和设置Redis key的序列化器两任务,最后返回RedisTemplate类的实例。

@Configuration
@Slf4j
public class RedisConfiguration {@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {log.info("开始创建Redis模板对象");RedisTemplate redisTemplate = new RedisTemplate();//设置Redis连接工厂对象redisTemplate.setConnectionFactory(redisConnectionFactory);//设置Redis key的序列化器redisTemplate.setKeySerializer(new StringRedisSerializer());return redisTemplate;};
}

四、通过RedisTemplate对象操作Redis

        我们可以先调用测试方法来测试RedisTemplate对象是否能够成功创建,在server模块下的test-java包中新建与启动类一致的目录层级:com.sky.test.SpringDataRedisTest,然后添加相关注解并注入RedisTemplate:

@SpringBootTest
public class SpringDataRedisTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testRedis() {System.out.println(redisTemplate);}
}

        如果测试通过即代码 RedisTemplate对象可以被成功创建:

        后续操作Redis都会使用到注入的RedisTemplate对象redisTemplate。之前介绍过Redis中的五种数据类型,每种数据类型的操作命令都不同, 在redisTemplate也封装了五个接口用于操作对应的数据:

@Test
public void testRedis() {// 打印redisTemplate实例,用于确认Redis模板是否已经成功注入System.out.println(redisTemplate);// 获取ValueOperations对象,用于执行Redis字符串类型的操作ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();// 获取HashOperations对象,用于执行Redis哈希表类型的操作HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();// 获取ListOperations对象,用于执行Redis列表类型的操作ListOperations<String, String> listOperations = redisTemplate.opsForList();// 获取SetOperations对象,用于执行Redis集合类型的操作SetOperations<String, String> setOperations = redisTemplate.opsForSet();// 获取ZSetOperations对象,用于执行Redis有序集合类型的操作ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
}

        接下来学习如何在java程序中通过Spring Data Redis来操作Redis当中的数据。

Idea使用Redis

        其同样根据类型的不同,操作方法也不同。先来看如何操作Redis中字符串类的数据。

一、字符串操作命令

        其虽在Redis中保存的类型为字符串,但与java中的String仍略有不同,因此在idea中可将其视为Object类来操作,也就是说可以传入任何数据,系统会将其转为Redis的String类型再存入数据库。同理,其返回值也是Object类型,想要使用String类型接收则需强转。

        上文介绍给字符串类型的常用操作命令共有四个SET、GET、SETEX、SETNX,其在java程序中也有着对应的方法。两者之间有一定相似,但又大有不同。
        我们着重介绍SETEX命令对应的方法,也就是指定key在指定时间后过期的方法。该方法前两个参数同样为key和value,第三个参数表示键值对的过期时间,即这个键值对将在X个时间单位后过期。第四个参数,是一个枚举类型,用于指定过期时间的单位。在这个例子中,TimeUnit.MINUTES表示过期时间的单位是分钟,即key2会在三分钟后过期。

@SpringBootTest
public class SpringDataRedisTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testString() {// 打印redisTemplate的引用,主要用于调试查看是否注入成功System.out.println(redisTemplate);// 使用ValueOperations设置一个键值对,键为"key1",值为"value1"redisTemplate.opsForValue().set("key1", "value1");// 从Redis中获取键为"key1"的值,并将其转换为String类型String key1 = (String) redisTemplate.opsForValue().get("key1");System.out.println(key1);// 设置一个带有过期时间的键值对,键为"key2",值为"value2",过期时间为3分钟redisTemplate.opsForValue().set("key2", "value2", 3, TimeUnit.MINUTES);// 使用setIfAbsent方法尝试设置键值对,只有当键不存在时才会设置成功// 如果"key3"不存在,则设置"key3"的值为"value3"redisTemplate.opsForValue().setIfAbsent("key3", "value3");// 再次尝试设置"key3",由于"key3"已经存在,这个操作不会改变"key3"的值redisTemplate.opsForValue().setIfAbsent("key3", "value3");}
}

        同时在图形工具中我们可以看到,key的值与idea中设置的值一致,但value却是"乱码",这是因为在RedisConfiguration类中我们使用语句

redisTemplate.setKeySerializer(new StringRedisSerializer());

设置了Redis key的序列化器,如果将该语句注释掉,系统会使用默认的序列化器,key的值也会变为乱码。

二、哈希操作命令

        哈希常用的操作命令有五个HSET、HGET key field、HDEL key field、HKEYS key、HVALS key。

    @Testpublic void testHashOperations() {// 获取哈希操作对象,用于执行哈希相关的Redis命令HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();// 将键值对存入哈希表,其中"user"是哈希表的键,"username"是字段,"jack"是值hashOperations.put("user", "username", "jack");// 将另一个键值对存入同一个哈希表,"age"是字段,"32"是值hashOperations.put("user", "age", "32");// 从哈希表中获取字段"username"的值String name = (String) hashOperations.get("user", "username");// 打印获取到的用户名System.out.println(name); // 应该输出 "jack"// 获取哈希表"user"中所有的字段Set<Object> keys = hashOperations.keys("user");// 打印所有字段System.out.println(keys); // 应该输出包含 "username" 和 "age" 的集合// 获取哈希表"user"中所有的值List<Object> values = hashOperations.values("user");// 打印所有值System.out.println(values); // 应该输出包含 "jack" 和 "32" 的列表// 从哈希表中删除字段"username"hashOperations.delete("user", "username");// 此时,哈希表"user"中应该只剩下字段"age"和它的值"32"}

三、列表操作命令

        其大致相同,不再赘述,直接看代码:

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

四、集合操作命令 

@Test
public void testSet() {//sadd smembers scard sinter sunion srem// 创建一个用于集合操作的实例SetOperations<String, String> setOperations = redisTemplate.opsForSet();// 向集合set1添加元素 a, b, c, dsetOperations.add("set1", "a", "b", "c", "d");// 向集合set2添加元素 a, b, x, ysetOperations.add("set2", "a", "b", "x", "y");// 获取集合set1的所有成员Set<String> members = setOperations.members("set1");System.out.println(members);// 获取集合set1的大小Long size = setOperations.size("set1");System.out.println(size);// 计算集合set1和set2的交集Set<String> intersect = setOperations.intersect("set1", "set2");System.out.println(intersect);// 计算集合set1和set2的并集Set<String> union = setOperations.union("set1", "set2");System.out.println(union);// 从集合set1中移除元素 a 和 bsetOperations.remove("set1", "a", "b");
}
//控制台输出
[d, c, b, a]
4
[b, a]
[x, d, a, c, b, y]

 

五、有序集合操作命令

    @Testpublic void testZset() {//zadd zrange zincrby zrem// 获取有序集合操作实例ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();// 向有序集合添加元素及其分数zSetOperations.add("zset1", "a", 10);zSetOperations.add("zset1", "b", 12);zSetOperations.add("zset1", "c", 9);// 获取有序集合中的所有元素Set<String> zset1 = zSetOperations.range("zset1", 0, -1);System.out.println(zset1);// 增加元素c的分数zSetOperations.incrementScore("zset1", "c", 10);// 从有序集合中移除元素a和bzSetOperations.remove("zset1", "a", "b");}

六、通用命令

        上述命令操作前,都需先获取对应的Operations对象然后再进行操作,但通用命令可直接通过RedisTemplate类的实例redisTemplate来操作。

    @Testpublic void testCommon() {//keys exists type del// 获取所有键Set keys = redisTemplate.keys("*");System.out.println(keys);// 检查特定键是否存在Boolean nameExists = redisTemplate.hasKey("name");Boolean set1Exists = redisTemplate.hasKey("set1");// 遍历所有键并打印其数据类型for (Object key : keys) {DataType dataType = redisTemplate.type(key);System.out.println(dataType.name());}// 删除指定键redisTemplate.delete("mylist");}
//控制台输出
[set2, mylist, set1, key3, user, zset1, key1]
SET
LIST
SET
STRING
HASH
ZSET
STRING

        此时各功能均已简单介绍,因此测试各功能是在测试类中进行的, 在苍穹外卖项目中并不需要该测试类及其内部的方法,为避免测试类拖慢项目启动速度,我们可以将测试类上方的@SpringBootTest注释掉。

店铺营业状态设置

        店铺左上角有一营业信息表示是否营业,点击右上角的营业状态设置可修改营业信息。
        当前餐厅处于营业状态时,当前餐厅处于打烊状态时,仅接受营业时间内的预定订单,可点击营业中手动恢复营业状态。

        接下来分析所需的接口,首先是左上角查询营业信息需要一个查询接口,同时不仅商家需要查询是否营业的接口,用户的小程序也需类似的接口,从技术层面来说两者可共用一个接口,但在该项目中为了规范请求路径(管理端发出的请求统一使用/admin作为前缀、用户端发出的请求统一使用/user作为前缀),我们选择将其设计为两个不同的接口。

        分析所需接口,首先上文提到的"管理端查询营业状态"、"用户端查询营业状态两接口",然后是设置营业状态所需的接口,我们依次来看。

设置营业状态

        首先是设置营业状态,营业状态的值可通过多种方式传到后端:url地址、请求体、路径参数,在本项目我们选择通过路径参数传递值。

        请求路径/admin/shop/{status},请求方法put,传递的值为1则表示营业,0为打烊。

        存储营业信息的数据表只需一个字段表示状态,且只需要一列数据用于存储0或1,为了存储这一数据来单独新开一个MySQL表不合理,因此我们选择将其存储到Redis数据库中,选择基于Redis的字符串来进行存储。

@RestController
@RequestMapping("/admin/shop")
@Api(tags = "店铺相关接口")
@Slf4j
public class ShopControlller {public static final String KEY = "SHOP_STATUS"; // 定义一个常量,用于Redis中存储店铺状态的键名@Autowired // 自动注入RedisTemplate实例,用于操作Redisprivate RedisTemplate redisTemplate;@PutMapping("/{status}")@ApiOperation("设置店铺的营业状态")public Result setStatus(@PathVariable Integer status) { // 接收路径变量status作为方法参数log.info("设置店铺的营业状态为:{}", status == 1 ? "营业中" : "打烊中");redisTemplate.opsForValue().set(KEY, status); // 将店铺状态存储到Redis中,使用定义的KEY作为键return Result.success();}
}

管理端查询营业状态

        请求路径/admin/shop/status,请求方法get。

    @GetMapping("/status")@ApiOperation("获取店铺营业状态") // 使用@ApiOperation注解描述该接口的功能,即获取店铺的营业状态public Result<Integer> getStatus() { // 定义一个返回类型为Result<Integer>的方法Integer shopStatus = (Integer) redisTemplate.opsForValue().get(KEY); // 从Redis中获取店铺状态log.info("获取到的店铺营业状态为:{}", shopStatus == 1 ? "营业中" : "打烊中"); // 记录日志,输出获取到的店铺状态return Result.success(shopStatus); // 返回包含店铺状态的Result对象}

用户端查询营业状态

        请求路径/user/shop/status,请求方法get。因为该功能为用户端的功能,为和管理端区分,我们需新建一个user包用于保存相关代码

        然后将admin包的ShopController类复制到该包下并修改相关信息,再删除修改营业状态的信息。由于两包中的类名称一致,导致其生成的bean名称也一致,同时放到IOC容器中会发生冲突,因此需手动为两类指定bean的名称,分别修改两类的注解为@RestController("userShopController")和@RestController("adminShopController")。

@RestController("userShopController")
@RequestMapping("/user/shop")
@Api(tags = "用户相关接口")
@Slf4j
public class ShopController {public static final String KEY="SHOP_STATUS";@Autowired // 自动注入RedisTemplate实例private RedisTemplate redisTemplate;@GetMapping("/status")@ApiOperation("获取店铺营业状态") // 使用@ApiOperation注解描述该接口的功能,即获取店铺的营业状态public Result<Integer> getStatus() { // 定义一个返回类型为Result<Integer>的方法Integer shopStatus = (Integer) redisTemplate.opsForValue().get(KEY); // 从Redis中获取店铺状态log.info("获取到的店铺营业状态为:{}", shopStatus == 1 ? "营业中" : "打烊中"); // 记录日志,输出获取到的店铺状态return Result.success(shopStatus); // 返回包含店铺状态的Result对象}
}

        代码已完成,开始测试,测试前先删除Redis数据库中的数据,点击对应图标并输入"yes"可快速删除所有数据:

 

 

        此时无论是管理端接口还是用户端接口都在同一个接口文档下,不便管理,我们可以修改用于生成接口文档的server模块config包WebMvcConfiguration类的docket(),修改接口文档需要扫描的包,使其只扫描管理端接口。
        再新建一个Docket类方法用于生成用户端接口的接口文档,并通过.groupName()方法,传入字符串来指定接口:

    @Beanpublic Docket adminDocket() {ApiInfo apiInfo = new ApiInfoBuilder().title("苍穹外卖项目接口文档title").version("2.0").description("苍穹外卖项目接口文档desc").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;}/*** 用户端接口文档* @return*/@Beanpublic Docket userDocket() {ApiInfo apiInfo = new ApiInfoBuilder().title("苍穹外卖项目接口文档title").version("2.0").description("苍穹外卖项目接口文档desc").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;}

        此时在接口文档页面就可以通过下拉列表区分不同的接口文档:

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

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

相关文章

Node.js 如何实现文件夹内文件批量重命名

文章目录 一、引言二、Node.js 简介2.1 是什么2.2 优势 三、Node.js 批量重命名原理3.1 涉及的核心模块3.2 关键函数 四、实战步骤4.1 环境搭建4.2 代码实现4.3 代码解释 五、案例分析5.1 场景描述5.2 解决方案 六、可能遇到的问题与解决方法6.1 常见错误6.2 解决方案 七、总结…

MySQL(高级特性篇) 04 章——逻辑架构

一、逻辑架构剖析 &#xff08;1&#xff09;服务器处理客户端请求 那服务器进程对客户端进程发送的请求做了什么处理&#xff0c;才能产生最后的处理结果呢&#xff1f;这里以查询请求为例展示&#xff1a;下面具体展开看一下&#xff1a;Connectors是MySQL服务器之外的客户…

滚动字幕视频怎么制作

在当今的视频创作领域&#xff0c;滚动字幕被广泛应用于各种场景&#xff0c;为视频增添丰富的信息展示和独特的视觉效果。无论是影视剧中的片尾字幕、新闻节目中的资讯滚动&#xff0c;还是综艺节目中的人员与鸣谢信息展示&#xff0c;滚动字幕都发挥着不可或缺的作用。接下来…

源码编译安装httpd 2.4,提供系统服务管理脚本并测试(两种方法实现)

方法一&#xff1a;使用 systemd 服务文件 sudo yum install gcc make autoconf apr-devel apr-util-devel pcre-devel 1.下载源码 wget https://archive.apache.org/dist/httpd/httpd-2.4.46.tar.gz 2.解压源码 tar -xzf httpd-2.4.46.tar.gz 如果没有安装tar 记得先安装…

计算机视觉算法实战——步态识别(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​​​​​​​​​​​​​​​​ 1. 步态识别简介✨✨ 步态识别&#xff08;Gait Recognition&#xff09;是计算机视觉领域中的一个…

2025 年 UI 大屏设计新风向

在科技日新月异的 2025 年&#xff0c;UI 大屏设计领域正经历着深刻的变革。随着技术的不断进步和用户需求的日益多样化&#xff0c;新的设计风向逐渐显现。了解并掌握这些趋势&#xff0c;对于设计师打造出更具吸引力和实用性的 UI 大屏作品至关重要。 一、沉浸式体验设计 如…

Leetcode - 周赛431

目录 一&#xff0c;3411. 最长乘积等价子数组 二&#xff0c;3412. 计算字符串的镜像分数 三&#xff0c;3413. 收集连续 K 个袋子可以获得的最多硬币数量 四&#xff0c;3414. 不重叠区间的最大得分 一&#xff0c;3411. 最长乘积等价子数组 本题数据范围小&#xff0c;直…

深入Android架构(从线程到AIDL)_30 JNI架构原理_Java与C的对接03

目录 2.4 以C结构表达类(class)&#xff0c;并创建对象(object) 认识C函数指针 范例 2.5 在C函数里存取对象的属性(attribute) 范例 2.4 以C结构表达类(class)&#xff0c;并创建对象(object) 认识C函数指针 struct里不能定义函数本身&#xff0c;但能定义函数指针(func…

论文笔记(四十七)Diffusion policy: Visuomotor policy learning via action diffusion(下)

Diffusion policy: Visuomotor policy learning via action diffusion&#xff08;下&#xff09; 文章概括5. 评估5.1 模拟环境和数据集5.2 评估方法论5.3 关键发现5.4 消融研究 6 真实世界评估6.1 真实世界Push-T任务6.2 杯子翻转任务6.3 酱汁倒入和涂抹任务 7. 实际双臂任务…

EasyExcel - 行合并策略(二级列表)

&#x1f63c;前言&#xff1a;博主在工作中又遇到了新的excel导出挑战&#xff1a;需要导出多条文章及其下联合作者的信息&#xff0c;简单的来说是一个二级列表的数据结构。 &#x1f575;️‍♂️思路&#xff1a;excel导出实际上是一行一行的记录&#xff0c;再根据条件对其…

软件测试面试题整理

一、人格相关问题 1、自我介绍结构 姓名工作年限简单介绍上家公司的行业主要负责内容个人优势短期内的职业规划应聘该岗位的原因 2、对未来的发展方向怎么看&#xff1f; 没有标准答案&#xff0c;职业规划来讲&#xff0c;可以分为技术层面和管理层面去说&#xff0c;技术…

.NET framework、Core和Standard都是什么?

对于这些概念一直没有深入去理解&#xff0c;以至于经过.net这几年的发展进化&#xff0c;概念越来越多&#xff0c;越来越梳理不容易理解了。内心深处存在思想上的懒惰&#xff0c;以为自己专注于Unity开发就好&#xff0c;这些并不属于核心范畴&#xff0c;所以对这些概念总是…

CNN张量输入形状和特征图

CNN张量输入形状和特征图 这个是比较容易理解的张量的解释&#xff0c;比较直观 卷积神经网络 在这个神经网络编程系列中&#xff0c;我们正在逐步构建一个卷积神经网络&#xff08;CNN&#xff09;&#xff0c;所以让我们看看CNN的张量输入。 ​ ​ 在最后两篇文章中&…

【数据可视化-12】数据分析岗位招聘分析

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

(12)springMVC文件的上传

SpringMVC文件上传 首先是快速搭建一个springMVC项目 新建项目mvn依赖导入添加webMoudle添加Tomcat运行环境.在配置tomcat时ApplicationContext置为"/"配置Artfact的lib配置WEB-INF配置文件&#xff08;记得添加乱码过滤&#xff09;配置springmvc-servlet文件&…

Ubuntu中双击自动运行shell脚本

方法1: 修改文件双击反应 参考: https://blog.csdn.net/miffywm/article/details/103382405 chmod x test.sh鼠标选中待执行文件&#xff0c;在窗口左上角edit菜单中选择preference设计双击执行快捷键&#xff0c;如下图&#xff1a; 方法2: 设置一个应用 参考: https://blo…

Linux(Centos7)安装Mysql/Redis/MinIO

安装Mysql 安装Redis 搜索Redis最先版本所在的在线安装yum库 查看以上两个组件是否是开机自启 安装MinIO 开源的对象存储服务&#xff0c;存储非结构化数据&#xff0c;兼容亚马逊S3协议。 minio --help #查询命令帮助minio --server --help #查询--server帮助minio serve…

金融项目实战 01|功能测试分析与设计

前置内容&#xff1a;金融项目准备的内容笔记可直接看如下笔记 只看&#xff1a;一、投资专业术语 和 二、项目简介 两部分文章浏览阅读2.3k次&#xff0c;点赞70次&#xff0c;收藏67次。安享智慧理财金融系统测试项目&#xff0c;测试用例&#xff0c;接口测试&#xff0c;金…

【Rust】控制流

目录 思维导图 一、选择结构 1. if表达式 2. 处理多个条件的else if 3. 使用if在let语句中 二、循环结构 1. loop 2. while循环 3. for循环 4. 使用范围Range进行循环 思维导图 一、选择结构 控制流是编程语言的基本构建块&#xff0c;Rust使用if表达式和循环来控制代…

FastDDS安装测试记录

1、安装依赖的软件 sudo apt install cmake g python3-pip wget git sudo apt install libasio-dev libtinyxml2-dev sudo apt install libssl-dev sudo apt install libp11-dev libengine-pkcs11-openssl sudo apt install softhsm22、安装foonathan_memory_vendor cd ~/Fas…