Swagger在线API文档

news2025/1/11 2:57:13

Swagger

解决的问题

随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了前后端分离的形态,而且前端技术和后端技术在各自的道路上越走越远。前端和后端的唯一联系,变成了 API 接口,所以 API 文档变成了前后端开发人员联系的纽带,变得越来越重要。

那么问题来了,随着代码的不断更新,开发人员在开发新的接口或者更新旧的接口后,由于开发任务的繁重,往往文档很难持续跟着更新,Swagger 就是用来解决该问题的一款重要的工具,对使用接口的人来说,开发人员不需要给他们提供文档,只要告诉他们一个 Swagger 地址,即可展示在线的 API 接口文档,除此之外,调用接口的人员还可以在线测试接口数据,同样地,开发人员在开发接口时,同样也可以利用 Swagger 在线接口文档测试接口数据,这给开发人员提供了便利。

Swagger 官方

我们打开 Swagger 官网,官方对 Swagger 的定义为:

The Best APIs are Built with Swagger Tools

翻译成中文是:“最好的 API 是使用 Swagger 工具构建的”。由此可见,Swagger 官方对其功能和所处的地位非常自信,由于其非常好用,所以官方对其定位也合情合理。如下图所示:

官方对swagger的定位

本文主要讲解在 Spring Boot 中如何导入 Swagger2 工具来展现项目中的接口文档。本节课使用的 Swagger 版本为 2.2.2。下面开始进入 Swagger2 之旅。

Swagger2 的 maven 依赖

使用 Swagger2 工具,必须要导入 maven 依赖,当前官方最高版本是 2.9.0,感觉页面展示的效果不太好,而且不够紧凑,不利于操作。另外,最新版本并不一定是最稳定版本,当前我们实际项目中使用的是 2.2.2 版本,该版本稳定,界面友好,所以本节课主要围绕着 2.2.2 版本来展开,依赖如下:

<!-- swagger -->
<swagger.version>2.9.2</swagger.version>            
<!-- swagger -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>${swagger.version}</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>${swagger.version}</version>
</dependency>

Swagger2 的配置

使用 Swagger2 需要进行配置,Spring Boot 中对 Swagger2 的配置非常方便,新建一个配置类,Swagger2 的配置类上除了添加必要的 @Configuration 注解外,还需要添加 @EnableSwagger2 注解。

.enable(flag) 可以通过配置文件来获取所属于的环境,赋值flag

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

/**
 * Title:Swagger2公共配置
 * Description:API在线文档
 * @author WZQ
 * @version 1.0.0
 * @date 2020/2/25
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {

    @Bean
    public Docket docket1() {
        return new Docket(DocumentationType.SWAGGER_2).groupName("内容1") // 分组名
                // 指定构建api文档的详细信息的方法:apiInfo()
                .apiInfo(apiInfo())
                //.enable(false) // 是否开启Swagger2,生产环境就要false,默认true
                .select()
                // 指定要生成api接口的包路径,.basePackage把controller作为包路径,生成controller中的所有接口
                // withClassAnnotation(RestController.class) RestController注解的类都要被描扫
                // withMethodAnnotation(GetMapping.class) GetMapping注解的方法都要被描扫
                .apis(RequestHandlerSelectors.basePackage("com.soft.one.ewms.business.user.controller.v1"))
                .paths(PathSelectors.any())
                // PathSelectors.ant("/url") 可限制url
                .build();
    }
    
    @Bean
    public Docket docket2() {
        return new Docket(DocumentationType.SWAGGER_2).groupName("内容2") // 分组名
                // 指定构建api文档的详细信息的方法:apiInfo()
                .apiInfo(apiInfo())
                //.enable(false) // 是否开启Swagger2,发布环境就要false,默认true
                .select()
                // 指定要生成api接口的包路径,.basePackage把controller作为包路径,生成controller中的所有接口
                // withClassAnnotation(RestController.class) RestController注解的类都要被描扫
                // withMethodAnnotation(GetMapping.class) GetMapping注解的方法都要被描扫
                .apis(RequestHandlerSelectors.basePackage("com.soft.one.ewms.business.user.controller.v1"))
                .paths(PathSelectors.any())
                // PathSelectors.ant("/url") 可限制url
                .build();
    }

    // localhost:8080/swagger-ui.html
    /**
     * 构建api文档的详细信息,作者信息,标题等
     * @return
     */
    private ApiInfo apiInfo() {
        // 作者信息
        Contact contact = new Contact("吴泽强","https://www.baidu.com/","@qq.com");
        // ApiInfo只有一个构造器
        return new ApiInfo(
                "Swagger2在线API文档",
                "Swagger2描述",
                "v1.0",
                "https://www.baidu.com/",
                contact,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList<>()
        );
    }
}

微服务模块引用

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan({"com.soft.one.ewms.configuration.swagger"}) //包名
public class SwaggerConfig {
}

启动项目,在浏览器中输入 localhost:8080/swagger-ui.html,即可看到 swagger2 的接口页面,如下图所示,说明Swagger2 集成成功。

在这里插入图片描述

Token验证ApiKey

加了认证权限框架,就需要验证,静态资源被拦截,即是需要token放在请求头。

在这里插入图片描述

如果加了spring security,只需要在对应服务上的WebSecurityConfiguration中配置

    // 忽略该地址,无需携带token,直接就可以被访问授权
    // 静态资源被拦截
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .antMatchers(AUTH_WHITELIST); // 忽略swagger ui静态资源
    }

    // -- swagger ui忽略
    private static final String[] AUTH_WHITELIST = {
            // -- swagger ui
            "/swagger-resources/**",
            "/swagger-ui.html",
            "/v2/api-docs",
            "/webjars/**"
    };

Swagger2 的使用

上面我们已经配置好了 Swagger2,并且也启动测试了一下,功能正常,下面我们开始使用 Swagger2,主要来介绍 Swagger2 中的几个常用的注解,分别在实体类上、 Controller 类上以及 Controller 中的方法上,最后我们看一下 Swagger2 是如何在页面上呈现在线接口文档的,并且结合 Controller 中的方法在接口中测试一下数据。

实体类注解

本节我们建一个 User 实体类,主要介绍一下 Swagger2 中的 @ApiModel@ApiModelProperty 注解,同时为后面的测试做准备。

required = true指该参数前端必须给,不可空

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(value = "用户实体类")
public class User {

    @ApiModelProperty(value = "用户唯一标识", required = true)
    private Long id;

    @ApiModelProperty(value = "用户姓名")
    private String username;

    @ApiModelProperty(value = "用户密码")
    private String password;

	// 省略set和get方法
}

解释下 @ApiModel@ApiModelProperty 注解:

@ApiModel 注解用于实体类,表示对类进行说明,用于参数用实体类接收。
@ApiModelProperty 注解用于类中属性,表示对 model 属性的说明或者数据操作更改。

该注解在在线 API 文档中的具体效果在下文说明。

Controller 类中相关注解

写几个接口,Controller 中和 Swagger2 相关的注解。

@RestController
@RequestMapping("/swagger")
@Api(tags = "Swagger2 在线接口文档")
public class TestController {
    
    @ApiOperation(value = "Sku条件分页查询",notes = "分页条件查询Sku方法详情",tags = {"SkuController"})
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "page", value = "当前页", required = true, dataType = "Integer"),
            @ApiImplicitParam(paramType = "path", name = "size", value = "每页显示条数", required = true, dataType = "Integer")
    })

    @GetMapping("/get/{id}")
    @ApiOperation(value = "根据用户唯一标识获取用户信息")
    public ResponseResult<User> getUserInfo(@PathVariable @ApiParam(value = "用户唯一标识") Long id) {
        // 模拟数据库中根据id获取User信息
        User user = new User(id, "倪升武", "123456");
        return new ResponseResult(user);
    }
}

我们来学习一下 @Api tags、 @ApiOperation@ApiParam 注解。

@Api 注解用于类上,表示标识这个类是 swagger 的资源。

@ApiOperation 注解用于方法,表示一个 http 请求的操作。

@ApiParam 注解用于参数上,用来标明参数信息。实体类。

@ApiImplicitParams 多参

@ApiImplicitParam 单个参数,不为实体

在浏览器中输入 localhost:8080/swagger-ui.html 看一下 Swagger 页面的接口状态。

swagger接口展示

可以看出,Swagger 页面对该接口的信息展示的非常全面,每个注解的作用以及展示的地方在上图中已经标明,通过页面即可知道该接口的所有信息,那么我们直接在线测试一下该接口返回的信息,输入id为1,看一下返回数据:

返回数据测试

可以看出,直接在页面返回了 json 格式的数据,开发人员可以直接使用该在线接口来测试数据的正确与否,非常方便。上面是对于单个参数的输入,如果输入参数为某个对象这种情况,Swagger 是什么样子呢?我们再写一个接口。

    @PostMapping("/insert")
    @ApiOperation(value = "添加用户信息")
    public ResponseResult<Void> insertUser(@RequestBody @ApiParam(value = "用户信息") User user) {
        // 处理添加逻辑
        return new ResponseResult<>();
    }

重启项目,在浏览器中输入 localhost:8080/swagger-ui.html 看一下效果:

swagger接口展示

Swagger2全局response

参考:https://www.jianshu.com/p/4539e312ce87

通过Swagger的全局配置,可以自定义默认的Response Model。

首先,在任何一个Controller上,添加至少一个@ApiResponses注解,标明response的类。

@ApiResponses({@ApiResponse(code = 500, message = "服务器内部错误", response = ApiError.class)})

然后,在Swagger配置类的Docket上加入globalResponseMessage,就是自定义状态码和消息,swagger2默认2**的。

@Bean
public Docket userApi() {
    List<ResponseMessage> responseMessageList = new ArrayList<>();
    responseMessageList.add(new ResponseMessageBuilder().code(404).message("找不到资源").responseModel(new ModelRef("ApiError")).build());
    responseMessageList.add(new ResponseMessageBuilder().code(409).message("业务逻辑异常").responseModel(new ModelRef("ApiError")).build());
    responseMessageList.add(new ResponseMessageBuilder().code(422).message("参数校验异常").responseModel(new ModelRef("ApiError")).build());
    responseMessageList.add(new ResponseMessageBuilder().code(500).message("服务器内部错误").responseModel(new ModelRef("ApiError")).build());
    responseMessageList.add(new ResponseMessageBuilder().code(503).message("Hystrix异常").responseModel(new ModelRef("ApiError")).build());

    return new Docket(DocumentationType.SWAGGER_2)

            .globalResponseMessage(RequestMethod.GET, responseMessageList)
            .globalResponseMessage(RequestMethod.POST, responseMessageList)
            .globalResponseMessage(RequestMethod.PUT, responseMessageList)
            .globalResponseMessage(RequestMethod.DELETE, responseMessageList)

            .build()
            .apiInfo(apiInfo());

}

请注意第一条不能省略,new ModelRef(“ApiError”),会查询之前定义@ApiResponse的response中指定的class

Swagger2导出html/pdf文件

依赖

<!-- swagger导出 -->
<swagger2markup.version>1.3.3</swagger2markup.version>
<!-- swagger导出 -->
<dependency>
    <groupId>io.github.swagger2markup</groupId>
    <artifactId>swagger2markup</artifactId>
    <version>${swagger2markup.version}</version>
</dependency>

插件

对应微服务中加入插件:

http://localhost:8080/v2/api-docs 对应微服务的端口号,原理有swagger把注解上的数据信息从v2/api-docs传json到swagger-ui页面显示的,这里我们获取json数据来生成。

生成路径是src/docs/asciidoc/generated

src/docs/asciidoc/html

src/docs/asciidoc/pdf

    <build>
        <plugins>
            <plugin>
                <groupId>io.github.swagger2markup</groupId>
                <artifactId>swagger2markup-maven-plugin</artifactId>
                <version>1.3.7</version>
                <configuration>
                    <!--此处定要是当前项目启动所用的端口-->
                    <swaggerInput>http://localhost:8080/v2/api-docs</swaggerInput>
                    <!-- adoc文档所在目录 -->
                    <outputDir>src/docs/asciidoc/generated</outputDir>
                    <config>
                        <!-- 除了ASCIIDOC之外,还有MARKDOWN和CONFLUENCE_MARKUP可选 -->
                        <swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage>
                    </config>
                </configuration>
            </plugin>
            <!--此插件生成HTML和PDF-->
            <plugin>
                <groupId>org.asciidoctor</groupId>
                <artifactId>asciidoctor-maven-plugin</artifactId>
                <version>2.0.0-RC.1</version>
                <!-- Include Asciidoctor PDF for pdf generation -->
                <dependencies>
                    <dependency>
                        <groupId>org.asciidoctor</groupId>
                        <artifactId>asciidoctorj-pdf</artifactId>
                        <version>1.5.0-alpha.18</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jruby</groupId>
                        <artifactId>jruby-complete</artifactId>
                        <version>9.2.7.0</version>
                    </dependency>
                </dependencies>
                <!-- Configure generic document generation settings -->
                <configuration>
                    <sourceDirectory>src/docs/asciidoc/generated</sourceDirectory>
                    <sourceHighlighter>coderay</sourceHighlighter>
                    <attributes>
                        <toc>left</toc>
                    </attributes>
                </configuration>
                <!-- Since each execution can only handle one backend, run
                     separate executions for each desired output type -->
                <executions>
                    <execution>
                        <id>output-html</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>html5</backend>
                            <outputDirectory>src/docs/asciidoc/html</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>output-pdf</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>pdf</backend>
                            <outputDirectory>src/docs/asciidoc/pdf</outputDirectory>
                        </configuration>
                    </execution>

                </executions>
            </plugin>
        </plugins>
    </build>

执行

mvn swagger2markup:convertSwagger2markup生成adoc文件(或者 mvn asciidoctor process-asciidoc)

这样也行,一般第二个就可以了,第一个可能异常。

在这里插入图片描述

然后使用命令:mvn generate-resources 生成html和pdf文件

插件命令可能找不到依赖,在父工程加入:

   <pluginRepositories>
        <pluginRepository>
            <id>spring-io</id>
            <name>Spring Io</name>
            <url>https://repo.spring.io/plugins-release</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

或者无法读取http://localhost:8080/v2/api-docs

可能是swagger加了分组,需要http://localhost:8080/v2/api-docs?group=分组名

如果分组名是中文也会报错,改成英文或者如下注入"UTF-8"

@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
   TomcatEmbeddedServletContainerFactory tomcat=new TomcatEmbeddedServletContainerFactory();
   tomcat.setUriEncoding(Charset.forName("UTF-8"));
   tomcat.setPort(8080);
   return tomcat;
}

pdf中文展示

可能有点麻烦,一般建议html就行,pdf中文展示会报大量错误,如果需要,参考:

https://www.jianshu.com/p/7f96f3c30587

swagger-bootstrap-ui

文档页面更友好。

该开源项目中文文档地址: https://doc.xiaominfo.com/

依赖:

<!-- swagger -->
<swagger.version>2.9.2</swagger.version>
<!-- swagger bootstrap ui -->
<swagger-bootstrap.version>1.9.6</swagger-bootstrap.version>

<!-- swagger -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>        
    <version>${swagger.version}</version>          
</dependency>

<dependency>            
    <groupId>com.github.xiaoymin</groupId>         
    <artifactId>swagger-bootstrap-ui</artifactId>          
    <version>${swagger-bootstrap.version}</version>      
</dependency>

配置:

package com.wzq.garbage.security.config;

import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * Title:swagger-Bootstrap-ui
 * Description:配置
 * @author WZQ
 * @version 1.0.0
 * @date 2021/3/28
 */
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
public class SwaggerConfiguration {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.wzq.garbage.security.controller"))
                .paths(PathSelectors.any())
                .build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("垃圾减量分类系统在线文档API")
                .description("登录认证微服务模块swagger-bootstrap-ui RESTful APIs")
                .termsOfServiceUrl("http://localhost:8001/")
                .contact("developer@mail.com")
                .version("1.0")
                .build();
    }
}

然后访问地址:http://ip:port/doc.html 即可,注解用法跟swagger一样。

SpringSecurity配置过滤

WebSecurityConfiguration类

 	@Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .antMatchers(AUTH_WHITELIST); // 忽略swagger ui静态资源
    }

    // -- swagger ui忽略
    private static final String[] AUTH_WHITELIST = {
            // -- swagger ui
            "/swagger-resources/**",
            "/swagger-ui.html",
            "/v2/api-docs",
            "/webjars/**",
            // swagger-boostrap-ui
            "/doc.html"
    };

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

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

相关文章

C++进阶---C++11

本篇主要是介绍C11中新添加的一些特性。 文章目录 1.C11简介2.列表初始化3.变量类型推导4.新增容器---静态数组array5.右值引用6.lambda表达式7.包装器8.新的类功能9.可变参数模板一、C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字…

Python高阶函数装饰器

“ 从CANoe vTESTstudio版本7开始&#xff0c;支持使用python编辑器编写python脚本。其中CANoe提供了许多API接口给python使用&#xff0c;大大扩展了python的可用性。在python中使用装饰器定义capl中的事件处理程序&#xff08;on key/on timer等&#xff09;。对此我们有必要…

C语言—宏定义

宏定义的作用是替换&#xff0c;再复杂也只能替换&#xff0c;不能用做计算&#xff1b; 一个源文件将另一个源文件的全部内容包含进来&#xff1b; 条件编译&#xff1b; 不带参数的宏定义&#xff1a; #include <stdio.h> #define PI 3.14int main() {printf("…

聊聊Redis消息队列-实现异步秒杀

一、前言 消息队列&#xff08;Message Queue&#xff09;, 字面意思就是存放消息的队列&#xff0c;最简单的消息队列模型包括3个角色&#xff1a; 消息队列&#xff1a;存储和管理消息&#xff0c;也被称为消息代理&#xff08;Message Broker&#xff09;;生产者&#xff…

Shell编程补充

Shell编程补充shell的变量定义变量的单双引号的不同输出变量父子shellshell子串BASHshell子串的用法shell统计变量长度输出程序运行时间结论:shell扩展变量用于处理变量值的创建子shell(进程列表)查看是否开启子shell在运行内置命令,外置命令shell编程总结shell的变量 定义变量…

小黑实习debug中遇到了函数式编程的混乱,特此进行的日常积累:python函数积累1

函数参数中有默认值&#xff0c;在函数内部会创建一块区域并维护这个默认值 # 在函数内存中会维护一块区域存储 [1,2,666,666,666] 100010001 def func(a1,a2[]):a2.append(666)print(a1,a2)func(100) func(1000)100 [666] 1000 [666, 666] def func(a1,a2[]):a2.append(666…

【nowcoder】笔试强训Day7

目录 一、选择题 二、编程题 2.1Fibonacci数列 2.2合法括号序列判断 一、选择题 1.JAVA属于&#xff08; &#xff09;。 A 操作系统 B 办公软件 C 数据库系统 D 计算机语言 计算机软件主要分为系统软件与应用软件两大类。系统软件主要包括操作系统、语言处理系统、数…

three.js之形状缓冲几何体

文章目录简介例子解释其他圆弧矩形专栏目录请点击 简介 Shape用来定义一个二维形状平面 官网常常与ShapeGeometry(形状缓冲几何体)搭配使用 官网&#xff0c;我们可以下运行下面的例子 例子 <!DOCTYPE html> <html lang"en"><head><meta cha…

玩转GPT--在线文本生成项目[可入坑~科普系列]

文章目录前言效果页面说明文字个数top_KTop_Ptemperature聊天上下文关联记忆项目部署获取项目获取模型运行彩蛋总结前言 没办法&#xff0c;最近ChatGPT杀疯了&#xff0c;没忍住&#xff0c;还是想look&#xff0c;look。没办法&#xff0c;哪个帅小伙能够忍受的了一个可以和…

数学知识---数论(质数和约数)

文章目录 1.质数1.1质数的判定---试除法1.2分解质因数---试除法1.3筛质数2.约数2.1试除法求约数2.2约数个数2.3约数之和2.4最大公约数---欧几里得算法(辗转相除法)1.质数 质数是针对所有大于1的自然数定义的,在大于1的整数中,如果只包含1和本身这两个约数,就被定义成为质…

【SpringCloud Alibaba】 初始化Sentinel

Sentinel 概念 特征 主要特征 开源生态​ 开启控制台 初始化工程 Sentinel 概念 分布式系统的流量防卫兵。随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点&#xff0c;从流量控制、流量路由、熔断降级、系统自适应过载保护…

Biotin-PEG-NH2,Biotin-PEG-amine,生物素-PEG-氨基材料改性用化学试剂

英文名称&#xff1a;Biotin-PEG-NH2&#xff0c;Biotin-PEG-amine 中文名称&#xff1a;生物素-聚乙二醇-氨基 Biotin-PEG-NH2是氨基化PEG中的一种&#xff0c;他可以用于材料改性&#xff1b;氨基和很多基团可以反应&#xff0c;如&#xff1a;羧基&#xff0c;活性酯&…

JavaScript:封装单向链表10种常见的操作方法

链表的优势 1.要存储多个元素的时候&#xff0c;除了数组还可以选择链表。 2.与之数组不同的是&#xff0c;链表中的元素在内存中不必是连续的空间。 3.链表中的每个元素由一个存储元素本身的节点和一个指向下一个节点的引用(指针或者连接)组成。 相比于数组&#xff0c;链表有…

QGIS基础:根据字段属性值或基于规则进行分类符号化显示

以下操作是对数据进行分类符号化&#xff0c;下面是原始操作数据&#xff1a; 基于分类符号化的字段是如下所示&#xff08;ZDTZM&#xff09;: A B C D 找到数据图层&#xff0c;右键属性&#xff0c;找到【符号化】&#xff0c;点击如下所示的分类&#xff1a; 在【valu…

mysql数据库完整实例-“汽车维修”

mysql数据库创建&#xff0c;编写&#xff0c;查询&#xff0c;自定义函数实战案例 创建汽车修理数据库&#xff0c;并完成数据库编写&#xff1a; 本文分三个部分&#xff0c;第一部分为数据库的创建编写和基础查询&#xff0c;第二部分为关联查询等复杂查询方法&#xff0c…

实验四:完整性实验

【实验目的】 掌握实体完整性、参照完整性和用户自定义完整性的定义的维护方法 【实验内容】 要实现这样一个功能&#xff1a;医生根据药品价表选择处方药品&#xff0c;录入数量和使用天数&#xff0c;系统根据医生选择的药品和录入的信息自动生成处方主表和处方明细表。功能…

Flink-按键分区状态-算子状态-广播状态

文章目录1. 按键分区状态&#xff08;Keyed State&#xff09;1.2基本概念和特点1.3 支持的结构类型1.4 代码实现1.5 状态生存时间&#xff08;TTL&#xff09;2 算子状态&#xff08;Operator State&#xff09;2.1 基本概念和特点2.2 状态类型2.3 代码实现3. 广播状态&#x…

2022年安徽建筑施工塔式起重机(建筑特种作业)模拟题库及答案

百分百题库提供特种工&#xff08;塔式起重机&#xff09;考试试题、特种工&#xff08;塔式起重机&#xff09;考试真题、特种工&#xff08;塔式起重机&#xff09;证考试题库等,提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 87.塔式起重机滑轮上…

基于历史对比学习的时序知识图谱推理

时序知识图谱 知识图谱&#xff08;KGs&#xff09;作为人类知识的集合&#xff0c;在自然语言处理、推荐系统和信息检索等领域显示展现了很好的前景。传统的KG通常是一个静态知识库&#xff0c;它使用图结构数据拓扑&#xff0c;并以三元组&#xff08;s, p, o&#xff09;的…

自定义ContentProvider案例

自定义ContentProvider案例 1.条件准备 app5往外暴漏数据app7接收和操作远程数据图1 app5目录结构 图2 app7目录结构 2.参考代码 完整代码&#xff1a; https://download.csdn.net/download/weixin_41957626/87346497 1)app5的代码 &#xff08;1&#xff09;app5的entity&…