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

server/2025/1/16 20:28:33/

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.ppmy.cn/server/158907.html

相关文章

在 Alpine Linux 下通过 Docker 部署 PostgreSQL 服务器

简要介绍 Docker 是一个开源的容器化平台&#xff0c;它使得开发者能够轻松创建、部署和运行应用程序。通过使用 Docker&#xff0c;程序员可以把应用及其所有依赖打包在一个轻量级的容器中&#xff0c;这样可以确保在不同环境中的一致性。PostgreSQL&#xff08;简称 psql&am…

北邮团队在Nature Medicine发表MedFound——辅助疾病诊断的通用医学语言模型|顶刊速递·25-01-15

小罗碎碎念 这篇文章介绍了一个名为MedFound的通用医学语言模型&#xff0c;该模型拥有1760亿参数&#xff0c;通过大规模医学文本和真实世界临床记录的预训练&#xff0c;以及基于自引导策略的推理方法微调&#xff0c;能够辅助疾病诊断。 在多个专业领域内&#xff0c;无论是…

怎么分析网页游戏中的数据 官方API 数据挖掘 第三方工具Overwolf、LoLalytics

要分析里面“”这个游戏的数据&#xff0c;你可以采用以下几种方法&#xff1a; ### 1. 使用官方API - **注册和认证**&#xff1a;首先&#xff0c;在游戏的官方网站或API平台上注册一个开发者账号&#xff0c;并完成认证&#xff0c;以获取API密钥。 - **阅读API文档**&…

MySQL_JDBC编程

Java中操作数据库&#xff0c;最基础的方式就是JDBC 1.准备工作&#xff1a;需要引入MySQL的JDBC驱动包 &#x1f352;这种驱动包&#xff0c;属于“第三方库” 不是JDK里原生就有的&#xff0c;就需要通过其他途径下载下来并引入到项目中 2.把jar引入到项目中 import com.m…

【Vue3 入门到实战】2. OptionsAPI与CompositionAPI及setup

目录 1. 介绍 1.1 OptionsAPI 1.2 CompositionAPI 2. setup 2.1 setup 概述 2.2 setup 特点 2.3 setup 与OptionsAPI 的关系 2.4 setup语法糖 3. 总结 1. 介绍 1.1 OptionsAPI 选项式 API 是 Vue 2 中的传统模式&#xff0c;并且在 Vue 3 中仍然得到支持。它通过在组…

【搭建JavaEE】(2)Tomcat安装配置和第一个JavaEE程序

Tomcat–容器(Container) 下载 Apache Tomcat - Welcome! 下载完成 请求/响应 结构 测试 查看Jdk版本 改端口号localhost8080–>8099 学学人家以后牛逼了可以用自己名字当文件夹名 配置端口8099 找到server文件 用记事本打开 再打开另一个logging文件 ”乱码解决“步骤&…

GitHub打不开的解决方案

在国内github官网经常面临打不开或访问极慢的问题&#xff0c;那有什么好办法解决GitHub官网访问不了的问题&#xff1f;今天来教你几招轻松访问github官网。 首先我们说下github官网打不开的原因到底是什么。我们会发现&#xff0c;github偶尔可以打开&#xff0c;偶尔打不开&…

Linux-day06

第14章 进程管理&#xff08;重点&#xff09; 进程基本介绍 程序运行起来就是一个进程 1.程序和进程的关系 2.在Linux中有两种方式执行&#xff0c;一种叫前台&#xff0c;一种后台 ps指令详解 显示系统执行的进程 USER&#xff1a;进程执行用户 PID&#xff1a;进程号 …