golang 引入swagger(iris、gin)

golang 引入swagger(iris、gin)

在开发过程中,我们不免需要调试我们的接口,但是有些接口测试工具无法根据我们的接口变化而动态变化。文档和代码是分离的。总是出现文档和代码不同步的情况。这个时候就可以在我们项目中引入swagger,方便后期维护以及他人快速上手项目

0 下载swagger

# 1 安装swagger
# 在go.mod目录所在位置执行命令
go get -u github.com/swaggo/swag/cmd/swag# 查看是否安装成功
swag -v# 如果发现报错:zsh: command not found: swag,则需要手动编译生成swag
cd $GOPATH/pkg/mod/github.com/swaggo/swag@v1.16.2/cmd/swag/
sudo go build
sudo mv swag $GOPATH/bin
# 查看是否安装成功
swag -v 

在这里插入图片描述

1 iris引入swagger

①导入iris-contrib/swagger依赖

//安装swagger扩展,本项目使用的是iris最新版(iris/v12),因此需要安装iris-swagger/v12扩展go get -v "github.com/iris-contrib/swagger/swaggerFiles"
go get -v "github.com/iris-contrib/swagger/v12"

②添加对应swagger注解 & swag init生成docs

在项目对应文件添加swagger注解,并通过swag init生成docs
注意:如果代码中的swagger注释有修改,需要重新执行swag init生成文档

例如:我给controller添加注解:

package controllerimport ("encoding/json""github.com/kataras/iris/v12""github.com/kataras/iris/v12/mvc""myTest/demo_home/swagger_demo/iris/model""net/http"
)type UserController struct {Ctx iris.Context
}func (u *UserController) BeforeActivation(b mvc.BeforeActivation) {b.Handle(http.MethodGet, "/getAll", "GetAllUsers")
}// GetAllUsers @Summary 获取用户信息
// @Description 获取所有用户信息
// @Tags 用户
// @Accept json
// @Produce json
// @Router /user/getAll [get]
func (u *UserController) GetAllUsers() mvc.Result {//手动模拟从数据库查询到user信息resp := new(mvc.Response)resp.ContentType = "application/json"user1 := new(model.User)user1.Name = "zhangsan"user1.Age = 20user2 := new(model.User)user2.Name = "li4"user2.Age = 28users := []model.User{*user1, *user2}marshal, _ := json.Marshal(users)resp.Content = marshalresp.Code = http.StatusOKreturn resp
}
//在项目根目录执行swag init ( 默认会找当前目录下的 main.go 文件,如果不叫 main.go 也可以-g手动指定文件位置。)
swag init # swag init -g cmd/api/api.go -o cmd/api/docs (-o指定docs生成位置)

③main.go中引入swag生成doc包

在 main.go 中导入刚才生成的 docs 包

package mainimport ("github.com/iris-contrib/swagger/v12""github.com/iris-contrib/swagger/v12/swaggerFiles""github.com/kataras/iris/v12""myTest/demo_home/swagger_demo/iris/controller"_ "myTest/demo_home/swagger_demo/iris/docs" //引入docs包
)func main() {app := iris.New()controller.InitControllers(app)config := &swagger.Config{URL: "http://localhost:8080/swagger/doc.json", //The url pointing to API definition}app.Get("/swagger/{any}", swagger.CustomWrapHandler(config, swaggerFiles.Handler))app.Listen(":8080")
}

④运行程序访问ip:port/swagger/index.html页面

运行main.go,浏览器输入:http://localhost:8080/swagger/index.html

在这里插入图片描述

全部代码

Github:
https://github.com/ziyifast/ziyifast-code_instruction/tree/main/swagger_demo

项目结构:
在这里插入图片描述

main.go
package mainimport ("github.com/iris-contrib/swagger/v12""github.com/iris-contrib/swagger/v12/swaggerFiles""github.com/kataras/iris/v12""myTest/demo_home/swagger_demo/iris/controller"_ "myTest/demo_home/swagger_demo/iris/docs" # 引入生成的docs包
)func main() {app := iris.New()controller.InitControllers(app)config := &swagger.Config{URL: "http://localhost:8080/swagger/doc.json", //The url pointing to API definition}app.Get("/swagger/{any}", swagger.CustomWrapHandler(config, swaggerFiles.Handler))app.Listen(":8080")
}
controller/controllers.go
package controllerimport ("github.com/kataras/iris/v12""github.com/kataras/iris/v12/mvc"
)func InitControllers(app *iris.Application) {myMvc := mvc.New(app.Party("/user"))myMvc.Handle(new(UserController))
}
controller/user_controller.go
package controllerimport ("encoding/json""github.com/kataras/iris/v12""github.com/kataras/iris/v12/mvc""myTest/demo_home/swagger_demo/iris/model""net/http"
)type UserController struct {Ctx iris.Context
}func (u *UserController) BeforeActivation(b mvc.BeforeActivation) {b.Handle(http.MethodGet, "/getAll", "GetAllUsers")
}// GetAllUsers @Summary 获取用户信息
// @Description 获取所有用户信息
// @Tags 用户
// @Accept json
// @Produce json
// @Router /user/getAll [get]
func (u *UserController) GetAllUsers() mvc.Result {//手动模拟从数据库查询到user信息resp := new(mvc.Response)resp.ContentType = "application/json"user1 := new(model.User)user1.Name = "zhangsan"user1.Age = 20user2 := new(model.User)user2.Name = "li4"user2.Age = 28users := []model.User{*user1, *user2}marshal, _ := json.Marshal(users)resp.Content = marshalresp.Code = http.StatusOKreturn resp
}

2 gin引入swagger

①导入swaggo/gin-swagger依赖

// 引入gin及gin-swagger依赖
go get "github.com/gin-gonic/gin"
go get "github.com/swaggo/gin-swagger/swaggerFiles"
go get "github.com/swaggo/gin-swagger"

②添加对应swagger注解 & swag init生成docs

注意:如果代码中的swagger注释有修改,需要重新执行swag init生成文档
user_controller.go

package controllerimport (ret "myTest/demo_home/swagger_demo/gin/response""net/http""strconv""time""github.com/gin-gonic/gin"
)// Hello 测试
// @Summary      测试SayHello
// @Description  向你说Hello
// @Tags         测试
// @Accept       json
// @Produce      json
// @Param        who  query     string  true             "人名"
// @Success      200  {string}  string  "{"msg": "hello  lixd"}"
// @Failure      400  {string}  string  "{"msg": "who    are  you"}"
// @Router       /hello [get]
func Hello(c *gin.Context) {who := c.Query("who")if who == "" {c.JSON(http.StatusBadRequest, gin.H{"msg": "who are u?"})return}c.JSON(http.StatusOK, gin.H{"msg": "hello " + who})
}type LoginReq struct {Username string `json:"username"`Password string `json:"password"`
}
type LoginResp struct {Token string `json:"token"`
}// Login 登陆
// @Summary      登陆
// @Tags         登陆注册
// @Description  登入
// @Accept       json
// @Produce      json
// @Param        user  body      LoginReq                    true  "用户名密码"
// @Success      200   {object}  ret.Result{data=LoginResp}  "token"
// @Failure      400   {object}  ret.Result                  "错误提示"
// @Router       /login [post]
func Login(c *gin.Context) {var m LoginReqif err := c.ShouldBind(&m); err != nil {c.JSON(http.StatusBadRequest, ret.Fail("参数错误"))return}if m.Username == "admin" && m.Password == "123456" {resp := LoginResp{Token: strconv.Itoa(int(time.Now().Unix()))}c.JSON(http.StatusOK, ret.Success(resp))return}c.JSON(http.StatusUnauthorized, ret.Fail("user  or  password  error"))
}

③main.go中引入swag生成doc包

package mainimport ("github.com/gin-gonic/gin"ginSwagger "github.com/swaggo/gin-swagger""github.com/swaggo/gin-swagger/swaggerFiles""myTest/demo_home/swagger_demo/gin/controller"_ "myTest/demo_home/swagger_demo/gin/docs"
)var swagHandler gin.HandlerFunc// @title           Swagger Example API
// @version         1.0
// @description     This is a sample server.
// @termsOfService  https://lixueduan.com// @contact.name   lixd
// @contact.url    https://lixueduan.com
// @contact.email  xueduan.li@gmail.com// @license.name  Apache 2.0
// @license.url   http://www.apache.org/licenses/LICENSE-2.0.html// @host      localhost:8080
// @BasePath  /api/v1// SwaggerUI: http://localhost:8080/swagger/index.html
func main() {e := gin.Default()v1 := e.Group("/api/v1"){v1.GET("/hello", controller.Hello)v1.POST("/login", controller.Login)}e.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))if swagHandler != nil {e.GET("/swagger/*any", swagHandler)}if err := e.Run(":8080"); err != nil {panic(err)}
}

resp.go:

// Package ret 统一返回结构
package retimport ("net/http"
)const (MsgSuccess = "success"MsgFail    = "fail"
)type Result struct {Code int         `json:"code"`Data interface{} `json:"data"`Msg  string      `json:"msg"`
}func Success(data interface{}, msg ...string) *Result {var m = MsgSuccessif len(msg) > 0 {m = msg[0]}return &Result{Code: http.StatusOK,Data: data,Msg:  m,}
}func Fail(msg ...string) *Result {var m = MsgFailif len(msg) > 0 {m = msg[0]}return &Result{Code: http.StatusBadRequest,Data: "",Msg:  m,}
}

④运行程序访问ip:port/swagger/index.html

http://localhost:8080/swagger/index.html

在这里插入图片描述

全部代码

地址:
https://github.com/ziyifast/ziyifast-code_instruction/tree/main/swagger_demo

main.go
package mainimport ("github.com/gin-gonic/gin"ginSwagger "github.com/swaggo/gin-swagger""github.com/swaggo/gin-swagger/swaggerFiles""myTest/demo_home/swagger_demo/gin/controller"_ "myTest/demo_home/swagger_demo/gin/docs"
)var swagHandler gin.HandlerFunc// @title           Swagger Example API
// @version         1.0
// @description     This is a sample server.// @contact.name   lixd
// @contact.name   ziyi
// @contact.url    https://github.com/ziyifast/ziyifast-code_instruction/tree/main/swagger_demo// @license.name  Apache 2.0
// @license.url   http://www.apache.org/licenses/LICENSE-2.0.html// @host      localhost:8080
// @BasePath  /api/v1// SwaggerUI: http://localhost:8080/swagger/index.html
func main() {e := gin.Default()v1 := e.Group("/api/v1"){v1.GET("/hello", controller.Hello)v1.POST("/login", controller.Login)}e.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))if swagHandler != nil {e.GET("/swagger/*any", swagHandler)}if err := e.Run(":8080"); err != nil {panic(err)}
}
controller/user_controller.go
package controllerimport (ret "myTest/demo_home/swagger_demo/gin/response""net/http""strconv""time""github.com/gin-gonic/gin"
)// Hello 测试
// @Summary      测试SayHello
// @Description  向你说Hello
// @Tags         测试
// @Accept       json
// @Produce      json
// @Param        who  query     string  true             "人名"
// @Success      200  {string}  string  "{"msg": "hello  lixd"}"
// @Failure      400  {string}  string  "{"msg": "who    are  you"}"
// @Router       /hello [get]
func Hello(c *gin.Context) {who := c.Query("who")if who == "" {c.JSON(http.StatusBadRequest, gin.H{"msg": "who are u?"})return}c.JSON(http.StatusOK, gin.H{"msg": "hello " + who})
}type LoginReq struct {Username string `json:"username"`Password string `json:"password"`
}
type LoginResp struct {Token string `json:"token"`
}// Login 登陆
// @Summary      登陆
// @Tags         登陆注册
// @Description  登入
// @Accept       json
// @Produce      json
// @Param        user  body      LoginReq                    true  "用户名密码"
// @Success      200   {object}  ret.Result{data=LoginResp}  "token"
// @Failure      400   {object}  ret.Result                  "错误提示"
// @Router       /login [post]
func Login(c *gin.Context) {var m LoginReqif err := c.ShouldBind(&m); err != nil {c.JSON(http.StatusBadRequest, ret.Fail("参数错误"))return}if m.Username == "admin" && m.Password == "123456" {resp := LoginResp{Token: strconv.Itoa(int(time.Now().Unix()))}c.JSON(http.StatusOK, ret.Success(resp))return}c.JSON(http.StatusUnauthorized, ret.Fail("user  or  password  error"))
}
response/response.go
// Package ret 统一返回结构
package retimport ("net/http"
)const (MsgSuccess = "success"MsgFail    = "fail"
)type Result struct {Code int         `json:"code"`Data interface{} `json:"data"`Msg  string      `json:"msg"`
}func Success(data interface{}, msg ...string) *Result {var m = MsgSuccessif len(msg) > 0 {m = msg[0]}return &Result{Code: http.StatusOK,Data: data,Msg:  m,}
}func Fail(msg ...string) *Result {var m = MsgFailif len(msg) > 0 {m = msg[0]}return &Result{Code: http.StatusBadRequest,Data: "",Msg:  m,}
}

3 注解

3.1 swagger主文件注解-通用API信息

注释说明示例
title必填 应用程序的名称// @title Swagger Example API
version必填 提供应用程序API的版本。// @version 1.0
description应用程序的简短描述。// @description This is a sample server celler server.
tag.name标签的名称。// @tag.name This is the name of the tag
tag.description标签的描述。// @tag.description Cool Description
tag.docs.url标签的外部文档的URL。// @tag.docs.url https://example.com
tag.docs.description标签的外部文档说明。// @tag.docs.description Best example documentation
termsOfServiceAPI的服务条款。// @termsOfService http://swagger.io/terms/
contact.name公开的API的联系信息。// @contact.name API Support
contact.url联系信息的URL。 必须采用网址格式。// @contact.url
contact.email联系人/组织的电子邮件地址。 必须采用电子邮件地址的格式。// @contact.email support@swagger.io
license.name必填 用于API的许可证名称。// @license.name Apache 2.0
license.url用于API的许可证的URL。 必须采用网址格式。// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
host运行API的主机(主机名或IP地址)。// @host localhost:8080
BasePath运行API的基本路径。// @BasePath /api/v1
acceptAPI 可以使用的 MIME 类型列表。 请注意,Accept 仅影响具有请求正文的操作,例如 POST、PUT 和 PATCH。 值必须如“Mime类型”中所述。// @accept json
produceAPI可以生成的MIME类型的列表。值必须如“Mime类型”中所述。// @produce json
query.collection.format请求URI query里数组参数的默认格式:csv,multi,pipes,tsv,ssv。 如果未设置,则默认为csv。// @query.collection.format multi
schemes用空格分隔的请求的传输协议。// @schemes http https
x-name扩展的键必须以x-开头,并且只能使用json值// @x-example-key {“key”: “value”}

通用api信息,部分可以是在docs包里生成的,可以在项目启动的时候,或者在注册swagger路由的时候,修改掉部分信息,或者动态注入部分不固定的值,比如项目的基础路径:BasePath

func NewRouter() *gin.Engine {gin.SetMode("debug")engine := gin.New()docs.SwaggerInfo.BasePath = "/api/v2"engine.POST("/", v1.GetWord)engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))engine.GET("/log/:id", client.ReadLokiLog)return engine
}

3.2 单个API样例

注释样例
description操作行为的详细说明。
description.markdown应用程序的简短描述。该描述将从名为endpointname.md的文件中读取。
id用于标识操作的唯一字符串。在所有API操作中必须唯一。
tags每个API操作的标签列表,以逗号分隔。
summary该操作的简短摘要。
acceptAPI 可以使用的 MIME 类型列表。 请注意,Accept 仅影响具有请求正文的操作,例如 POST、PUT 和 PATCH。 值必须如“Mime类型”中所述。
produceAPI可以生成的MIME类型的列表。值必须如“Mime类型”中所述。
param用空格分隔的参数。param name,param type,data type,is mandatory?,comment attribute(optional)
security每个API操作的安全性。
success以空格分隔的成功响应。return code,{param type},data type,comment
failure以空格分隔的故障响应。return code,{param type},data type,comment
response与success、failure作用相同
header以空格分隔的头字段。 return code,{param type},data type,comment
router以空格分隔的路径定义。 path,[httpMethod]
x-name扩展字段必须以x-开头,并且只能使用json值。

// @Summary 测试swagger
// @Tags test
// @version 1.0
// @Success 200 object FinalResult{data=v1.Application} 成功后返回值
// @Failure 500 object FinalResult 添加失败
// @Router / [get]
func GetWord(ctx *gin.Context) {application := &Application{Id: 1}err := ctx.BindJSON(application)if err != nil {ctx.JSON(500, "")}ctx.JSON(200, SuccessResult(application))
}

summary 是这个api的名字,可以显示在yapi的名称
tag 是这个api所在的分组
success 支持组合嵌套
param 说明了api需要的请求参数
param的类型支持:

  • query
  • path
  • header
  • body
  • formData

如果我们需要给字段添加注释,直接在字段后面添加即可

直接在参数属性后面增加注释,也可以指定参数的名称说明描述

type Application struct {Id   int    `json:"id" example:"2"`     // 环境IDName string `json:"name" example:"环境一"` // Name 环境名称
}

忽略某个字段:

type Account struct {ID   string    `json:"id"`Name string     `json:"name"`Ignored int     `swaggerignore:"true"`
}

注意:如果代码中的swagger注释有修改,需要重新执行swag init生成文档

参考:https://blog.csdn.net/qq_38371367/article/details/123005909

bug

1 unknown field LeftDelim in struct literal of type "github.com/swaggo/swag

注意:如果遇到报错:
docs/docs.go:30:2: unknown field LeftDelim in struct literal of type “github.com/swaggo/swag”.Spec
可能是由于swag版本过低导致,升级版本即可:go get -u -v github.com/swaggo/swag/cmd/swag

2 添加了swag 注解,访问页面成功,但没有对应的方法

重新执行swag init,然后重新启动项目

  • 如果代码中的swagger注解有修改,需要重新执行swag init生成文档

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

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

相关文章

【漏洞复现】多语言药房管理系统MPMS文件上传漏洞

Nx01 产品简介 多语言药房管理系统 (MPMS) 是用 PHP 和 MySQL 开发的, 该软件的主要目的是在药房和客户之间提供一套接口,客户是该软件的主要用户。该软件有助于为药房业务创建一个综合数据库,并根据到期、产品等各种参数提供各种报告。 Nx02 漏洞描述 …

显示器颜色显示技术原理

此图片来源于网络 1、人眼是如何看到颜色的 以下介绍如何定义颜色的基本知识。首先人眼是如何看到颜色的。可见光的光谱范围从380纳米到750纳米。在此范围内,可以看到每种可见颜色的相应波长。将讨论如何将可见光谱的波长组合成其他颜色,以及这一过程是…

2023年12月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 一个非零的二进制正整数,在其末尾添加两个“0”,则该新数将是原数的?( ) A:10倍 B:2倍 C:4倍 D:8倍 答案:C 二进制进位规则是逢二进一,因此末尾添加一个0,是扩大2倍,添加两个0…

postman执行批量测试

1.背景 有许多的人常常需要使用第三方系统进行重复的数据查询,本文介绍使用PostMan的方式对数据进行批量的查询,减少重复的劳动。 2.工具下载 3.初入门 一、如图示进行点击,创建collection 二、输入对应的名称 三、创建Request并进行查…

C++后端开发之Sylar学习二:配置VSCode远程连接Ubuntu开发

C后端开发之Sylar学习二:配置VSCode远程连接Ubuntu开发 没错,我不能像大佬那样直接在Ubuntu上面用Vim手搓代码,只能在本地配置一下VSCode远程连接Ubuntu进行开发咯! 本篇主要是讲解了VSCode如何配置ssh连接Ubuntu,还有…

无损音乐下载,最新音乐下载,mp3格式音乐下载,一键下载mp3格式音乐,我只用这个软件,歌曲资源丰富,全网音乐免费下载,稳定运行,告别收费

一、软件简介 现在很多支持一键下载mp3音乐/无损音质音乐的音乐播放器通常都是解析接口套了一个壳,一旦解析接口失效,软件就不能下载音乐了,因此一个稳定的解析接口是这类软件最大的保障。本次小编推荐的音乐下载软件接口非常稳定&#xff0…

单片机学习笔记---LED点阵屏的工作原理

目录 LED点阵屏分类 LED点阵屏显示原理 74HC595的介绍 一片74HC595的工作原理 多片级联工作原理 总结 LED点阵屏由若干个独立的LED组成,LED以矩阵的形式排列,以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种公共场合,如汽…

第五篇【传奇开心果系列】vant开发移动应用示例:深度解读高度可定制

传奇开心果博文系列 系列博文目录Vant 开发移动应用示例系列 博文目录前言一、Vant高度可定制的重要作用二、样式定制介绍和示例代码三、组件定制介绍和示例代码四、组件库定制介绍和示例代码五、主题定制介绍和示例代码六、语言环境定制介绍和示例代码七、资源加载定制介绍和示…

网络层DoS

网络层是OSI参考模型中的第三层,介于传输层和数据链路层之间,其目的 是实现两个终端系统之间数据的透明传送,具体功能包括:寻址和路由选择、连 接的建立、保持和终止等。位于网络层的协议包括ARP 、IP和ICMP等。下面就 ICMP为例&…

创建一个VUE项目(vue2和vue3)

背景:电脑已经安装完vue2和vue3环境 一台Mac同时安装vue2和vue3 https://blog.csdn.net/c103363/article/details/136059783 创建vue2项目 vue init webpack "项目名称"创建vue3项目 vue create "项目名称"

diffusers单机多卡推理(全网首发)

起因 博主在部署InstantID项目时,显存不够,想要将模型分散在多张卡上。 翻到这篇发现是分布式推理,博主一直以为这个可以达到我想要的效果,但是效果是多线程并行推理,并不能将一个模型切片在多个GPU上。 Distributed …

一起玩儿物联网人工智能小车(ESP32)——57. SPI总线协议初探(一)

摘要:介绍SPI总线的基本知识 前面已经学习过IIC总线协议,今天开始介绍另一个总线协议——SPI。SPI(Serial Peripheral Interface,串行外设接口)是由Motorola提出的一种高速、全双工、同步的通信总线。并且在芯片的管脚…

TI的电量计驱动在卸载时导致Linux卡死

背景 最近移植TI电量计芯片bq40z50的驱动,移植完毕后,能正常读取电池信息了,但是无意中发现驱动卸载会导致Linux卡死,死前终端闪过大量打印,将putty的缓冲区都耗尽了,必须启用syslog转发并用visual syslog…

L1-080 乘法口诀数列

一、题目 二、解题思路 三、代码 #include<iostream> using namespace std; int main() {int a1,a2,n;cin>>a1>>a2>>n;if(n1){cout<<a1;return 0; }int a[n*2];cout<<a1<<" "<<a2;a[0]a1;a[1]a2;for(int i2,j2;i&l…

ubuntu20安装mongodb

方法一&#xff1a;直接安装(命令是直接从mongo官网Install MongoDB Community Edition on Ubuntu — MongoDB Manual复制的&#xff09; cat /etc/lsb-release sudo apt-get install -y gnupg curl curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \sudo gp…

背包问题(01背包、完全背包、多重背包)详解(超详细!!!),及题目代码和题意,包含6个例题。

第一题&#xff1a;01背包问题 01背包问题 时间限制&#xff1a;1秒 内存限制&#xff1a;128M 题目描述 一个旅行者有一个最多能装 M 公斤的背包&#xff0c;现在有 n 件物品&#xff0c;它们的重量分别是 W1&#xff0c;W2&#xff0c;...,Wn ,它们的价值分别为 C1…

FXTM富拓监管变更!2024开年连续3家交易商注销牌照

交易商的监管信息是经常发生变更的&#xff0c;即使第一次投资时查询平台监管牌照&#xff0c;投资者仍需持续关注其监管动态。千万不要以为第一步审核好后就万事大吉了&#xff01; 2024年开年&#xff0c;就有3家交易商的重要信息发生变更&#xff0c;注销其金融监管牌照&…

专业课147总420+福州大学866信号与系统考研经验福大电子信息技术信息与通信

我本人一战双非上岸福大&#xff0c;初试分数420&#xff0c;期中专业课866信号与系统147&#xff08;有点遗憾没有达到信息通信考研Jenny老师辅导班要求的满分&#xff09;。这里想分享一些自己准备初试的过程和一些学习方法&#xff0c;希望能给各位准备报考福州大学866的学弟…

HiveSQL——借助聚合函数与case when行转列

一、条件函数 if 条件函数 if函数是最常用到的条件函数&#xff0c;其写法是if(xn,a,b), xn代表判断条件&#xff0c;如果xn时&#xff0c;那么结果返回a ,否则返回b。 selectif(age < 25 or age is null, 25岁以下, 25岁以上) as age_cnt,count(1) as number from table…

WifiConfigStore初始化读取-Android13

WifiConfigStore初始化读取 1、StoreData创建并注册2、WifiConfigStore读取2.1 文件读取流程2.2 时序图2.3 日志 1、StoreData创建并注册 packages/modules/Wifi/service/java/com/android/server/wifi/WifiConfigManager.java mWifiConfigStore.registerStoreData(mNetworkL…