Jenkins声明式Pipeline流水线语法示例

系列文章目录

docker搭建Jenkins2.346.3版本及常用工具集成配置(ldap、maven、ansible、npm等)
docker安装低版本的jenkins-2.346.3,在线安装对应版本插件失败的解决方法


文章目录

  • 系列文章目录
  • jenkins流水线基础
      • 1、pipeline
        • 1.1、什么是pipeline?
        • 1.2、为什么使用pipeline?
        • 1.3、pipeline定义
        • 1.4、jenkinsfile
        • 1.5、声明式pipeline示例
        • 1.6、参数解读
      • 2、声明式流水线语法
        • 2.1、pipeline语法-agent(代理)
        • 2.2、post
        • 2.3、stages(阶段)
        • 2.4、steps(步骤)
          • 2.4.1、script
        • 2.5、指令
          • 2.5.1、environment
          • 2.5.2、options
          • 2.5.3、参数
            • 参数构建化过程配置参数如下示例:
            • jenkinsfile中定义参数示例:
        • 2.6、触发器(trigger)
        • 2.7、tool
        • 2.8、input
        • 2.9、when
          • 内置条件
          • when使用示例
        • 2.10、parallel并行
  • 总结

jenkins流水线基础

首先,创建一个简单的流水线项目,体验并完成一条流水线项目的构建过程。如下图示
切记: 流水线的运行方式取决于定义的jenkinsfile

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1、pipeline

提前安装插件 Pipeline:Declarative
1.1、什么是pipeline?
1、pipeline是jenkins的核心功能,提供一组可扩展的工具
2、通过pipeline的DSL语法完成从简到难的交付流水线实现
3、jenkins的pipeline是通过jenkinsfile来实现的
4、这个文件可以定义jenkins的执行步骤,例如:代码拉取、代码检查等
1.2、为什么使用pipeline?
本质上,jenkins是一个自动化引擎,它支持许多自动模式。

流水线向Jenkins添加了一组强大的工具,支持用例、简单的持续集成到全面的持续交付流水线。 
通过对一系列的发布任务建立标准的模板,用户可以利用更多流水线的特性,比如:
	代码化: 流水线是在代码中实现的,通常会存放到源代码控制,使团队具有编辑、审查和更新他们项目的交付流水线的能力。
	耐用性: 流水线可以从Jenkins的master节点重启后继续运行。
	可暂停的: 流水线可以由人功输入或批准继续执行流水线。
	解决复杂发布: 支持复杂的交付流程。例如循环、并行执行。
	可扩展性: 支持扩展DSL和其他插件集成

在这里插入图片描述

1.3、pipeline定义
一条流水线通过Jenkinsfile描述
安装声明式插件Pipeline: Declarative
Jenkinsfile组成
	指定node节点/workspace
	指定指定运行选项
	指定stages阶段
	指定构建后操作
1.4、jenkinsfile
Jenkinsfile使用两种语法进行编写,分别是声明式和脚本式。
声明式和脚本式的流水线从根本上是不同的。
声明式是jenkins流水线更友好的特性。
脚本式的流水线语法,提供更丰富的语法特性。
声明式流水线使编写和读取流水线代码更容易设计。
声明式Pipeline: 使用agent指定运行的slave节点可以是label。
pipeline{
    agent any
    stages{
    //    
    }
}
脚本式Pipleine: 使用node指定运行slave可以是label
node("slave"){
    stage("GetCode"){
    //
    }
}
1.5、声明式pipeline示例
String workspace = "/home/vagrant/workspace" 

//Pipeline 
pipeline {
    agent { node { label "master"   //指定运行节点的标签或者名称
                     customWorkspace "${workspace}" //指定运行工作目录(可选)
            }
    }

    options { 
        timestamps()    //日志会有时间
        skipDefaultCheckout()  //删除隐式checkout scm 语句
        disableConcurrentBuilds()  //静止并行
        timeout(time: 1, unit: 'HOURS')  //流水线超时设置1h
    }

    stages { 
    //下载代码
        stage("GetCode"){   //阶段名称
            steps{   //名称
                timeout(time:5, unit:"MINUTES"){   //步骤超时时间
                    script{   //填写运行代码
                        println('获取代码') 
                    } 
                } 
            } 
        }
       //构建
        stage("Build"){ 
            steps{
                timeout(time:20, unit:"MINUTES"){ 
                    script{ 
                        println('应用打包')
                    }
                } 
            }
        }

        //代码扫描
        stage("CodeScan"){
            steps{ 
                timeout(time:30, unit:"MINUTES"){ 
                    script{ 
                        print('代码扫描')
                    } 
                }
            }
        }
    } 

    //构建后操作
    post {
        always { 
            script{ 
                println("always") 
            } 
        } 

        success {
            script{
                currentBuild.description += "\n 构建成功!" 
            } 
        }

        failure {
            script{ 
                currentBuild.description += "\n 构建失败!" 
            } 
        }

        aborted { 
            script{ 
                currentBuild.description += "\n 构建取消!" 
            } 
        } 
    } 
}
1.6、参数解读

Agent-Options

  • 指定node节点/workspace
  • 指定运行选项
  • 声明式Pipeline: 使用agent指定运行的slave节点可以是label
pipeline{
     agent { node { label "master"   //指定运行节点的标签或者名称
                     customWorkspace "${workspace}" //指定运行工作目录(可选)
            }
    }

    options { 
        timestamps()    //日志会有时间
        skipDefaultCheckout()  //删除隐式checkout scm 语句
        disableConcurrentBuilds()  //静止并行
        timeout(time: 1, unit: 'HOURS')  //流水线超时设置1h
    }

    
}

脚本式Pipleine: 使用node指定运行slave可以是label

node("slave"){
   options { 
        timestamps()    //日志会有时间
        skipDefaultCheckout()  //删除隐式checkout scm 语句
        disableConcurrentBuilds()  //静止并行
        timeout(time: 1, unit: 'HOURS')  //流水线超时设置1h
    }
}

Stages

  • stage定义了在整个流水线的执行任务的概念性的不同的阶段。例如: GetCodeBuildTestDeployCodeScan每个阶段。

  • 解释:上述示例添加了三个阶段

    • GetCode
    • Build
    • CodeScan
  • 声明式pipeline: 定义stages->stage

pipeline{
    agent any
    stages{
    stage("GetCode"){
        //steps  
    }

    stage("build"){
       //step
    }
  }
}
  • 脚本式Pipeline: 直接使用stage
node("slave"){
    stage("GetCode"){
    //
    }

    stage("build"){
    //
    }
}

step(步骤)

  • step是每个阶段中要执行的每个步骤。
  • 例如: 在执行GetCode的时候需要判断用户提供的参数srcType的值是Git还是svn
pipeline{
agent any
stages{
    stage("GetCode"){
        steps{ 
            sh "ls "    //step
            } 
        }    
    }
}
  • 脚本式Pipeline: 不需要step关键字。
node("slave"){
stage("GetCode"){
    //step
    if("${srcType}" == "Git"){
        //用git方式代码检出
    } else if ("${srcType}" == "SVN"){
        //用svn方式代码检出
    } else {
        error "srcType is not in [Git|SVN]"
    }
}
}

Post

  • 指定构建后操作
  • 解释:
    • always{}:总是执行脚本片段
    • success{}:成功后执行
    • failure{}:失败后执行
    • aborted{}:取消后执行
  • currendBuild是jenkins内部的全局变量
    • description:构建描述

2、声明式流水线语法

2.1、pipeline语法-agent(代理)
agent指定了流水线的执行节点
参数:
	any  在任何可以节点上执行pipeline
	none  没有指定agent的时候默认
	label 在指定标签的节点上执行pipeline
	node  允许额外的选项
语法示例一:
	agent {
		node {
			label 'labelname'
		}
	}
语法示例二:
	agent {
		label 'labelname'
	}
2.2、post
	定义一个或多个steps,这些阶段根据流水线或阶段的完成情况而运行(取决于流水线中post部分的位置),post支持以下post-condition块其中之一:always、changed、failure、success、unstable、aborted,这些条件块允许在post部分的步骤的执行取决于流水线阶段的完成状态。
	
always: 无论流水线或者阶段的完成状态。
changed: 只有当流水线或者阶段完成状态与之前不同时。
failure: 只有当流水线或者阶段状态为”failure”运行。
success: 只有当流水线或者阶段状态为”success”运行。
unstable: 只有当流水线或者阶段状态为”unstable”运行。例如:测试失败。
aborted: 只有当流水线或者阶段状态为”aborted “运行。例如:手动取消。
如下示例
pipeline {
agent any
stages {
    stage('Example') {
        steps {
            echo 'Hello World'
        }
    }
}
post { 
    always { 
        echo 'I will always say Hello again!'
    }
}
}
2.3、stages(阶段)
	包含一系列一个或多个stage指令,建议stages至少包含一个stage指令用于连续交付过程的每个离散部分,比如:构建、测试、部署等
pipeline {
    agent any
    stages { 
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}
2.4、steps(步骤)
每个阶段要执行的步骤
	pipeline {
    agent any
    stages {
        stage('Example') {
            steps { 
                echo 'Hello World'
            }
        }
    }
}
2.4.1、script
	script 步骤需要 [scripted-pipeline]块并在声明式流水线中执行。
	对于大多数用例来说,应该声明式流水线中的“脚本”步骤是不必要的,但是它可以提供一个有用的”逃生出口”。非平凡的规模和/或复杂性的script块应该被转移到 共享库 。
pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'

                script {
                    def browsers = ['chrome', 'firefox']
                    for (int i = 0; i < browsers.size(); ++i) {
                        echo "Testing the ${browsers[i]} browser"
                    }
                }
            }
        }
    }
}
2.5、指令
2.5.1、environment
	environment 指令指定一个键值对序列,也称为环境变量,该序列将被定义为所有步骤的环境变量,或者是特定于阶段的步骤,这取决于 environment 指令在流水线内的位置。
	该指令支持一个特殊的方法 credentials() ,该方法可用于在Jenkins环境中通过标识符访问预定义的凭证。对于类型为 “Secret Text”的凭证, credentials() 将确保指定的环境变量包含秘密文本内容。对于类型为 “SStandard username and password”的凭证, 指定的环境变量指定为 username:password ,并且两个额外的环境变量将被自动定义 :分别为 MYVARNAME_USR 和 MYVARNAME_PSW 。
pipeline {
    agent any
    environment { 
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment { 
                AN_ACCESS_KEY = credentials('my-prefined-secret-text') 
            }
            steps {
                sh 'printenv'
            }
        }
    }
}
2.5.2、options
	options 指令允许从流水线内部配置特定于流水线的选项。 
	流水线提供了许多这样的选项, 比如buildDiscarder,但也可以由插件提供, 比如 timestamps。
	buildDiscarder: 为最近的流水线运行的特定数量保存组件和控制台输出。
    disableConcurrentBuilds: 不允许同时执行流水线。 可被用来防止同时访问共享资源等。
    overrideIndexTriggers: 允许覆盖分支索引触发器的默认处理。
    skipDefaultCheckout: 在agent 指令中,跳过从源代码控制中检出代码的默认情况。
    skipStagesAfterUnstable: 一旦构建状态变得UNSTABLE,跳过该阶段。
    checkoutToSubdirectory: 在工作空间的子目录中自动地执行源代码控制检出。
    timeout: 设置流水线运行的超时时间, 在此之后,Jenkins将中止流水线。
    retry: 在失败时, 重新尝试整个流水线的指定次数。
    timestamps: 预测所有由流水线生成的控制台输出,与该流水线发出的时间一致。
//指定一个小时的全局执行超时, 在此之后,Jenkins将中止流水线运行。
pipeline {
agent any
options {
    timeout(time: 1, unit: 'HOURS') 
}
stages {
    stage('Example') {
        steps {
            echo 'Hello World'
        }
    }
}
}
2.5.3、参数

在这里插入图片描述

如上图所示,再上述位置配置的参数其实都可以再Jenkinsfile中定义实现
为流水线运行时设置项目相关的参数,参数定义的两种方法
	1、参数可以在这个参数化构建过程中定义,然后再Jenkinsfile中调用
	2、参数也可以再jenkinsfile中定义并使用参数
参数构建化过程配置参数如下示例:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

jenkinsfile中定义参数示例:

在这里插入图片描述

在这里插入图片描述

值得注意的是,当保存后再构建页面中是看不到新添加的参数,只有执行一次构建过程后,该页面才会有新添加的参数,如下所示

在这里插入图片描述

2.6、触发器(trigger)
定时去做某件事情时可以考虑使用,如下示例
  • cron 计划任务定期执行构建。

    triggers { cron('H */4 * * 1-5') }
    
  • pollSCM 与cron定义类似,但是由jenkins定期检测源码变化。

    triggers { pollSCM('H */4 * * 1-5') }
    
  • upstream 接受逗号分隔的工作字符串和阈值。 当字符串中的任何作业以最小阈值结束时,流水线被重新触发。

    triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS) }
    
pipeline {
agent any
triggers {
    cron('H */4 * * 1-5')
}
2.7、tool
	获取通过自动安装或手动放置工具的环境变量。支持maven/jdk/gradle。工具的名称必须在系统设置->全局工具配置中定义。
	使用示例如下: 在jenkinsfile中使用全局工具maven

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.8、input
input用户在执行各个阶段的时候,由人工确认是否继续进行。比较常用
    message 呈现给用户的提示信息。
    id 可选,默认为stage名称。
    ok 默认表单上的ok文本。
    submitter 可选的,以逗号分隔的用户列表或允许提交的外部组名。默认允许任何用户。
    submitterParameter 环境变量的可选名称。如果存在,用submitter 名称设置。
    parameters 提示提交者提供的一个可选的参数列表。
如下示例:
	1、使用流水线语法生成一个示例input
	2、将生成的input粘贴至pipeline
	3、执行构建,查看是否有提示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.9、when
	when 指令允许流水线根据给定的条件决定是否应该执行阶段。 
	when 指令必须包含至少一个条件。 
	如果when 指令包含多个条件, 所有的子条件必须返回True,阶段才能执行。 
	这与子条件在 allOf 条件下嵌套的情况相同。
内置条件
  • branch: 当正在构建的分支与模式给定的分支匹配时,执行这个阶段,这只适用于多分支流水线例如:

    when { branch 'master' }
    
  • environment: 当指定的环境变量是给定的值时,执行这个步骤,例如:

    when { environment name: 'DEPLOY_TO', value: 'production' }
    
  • expression 当指定的Groovy表达式评估为true时,执行这个阶段, 例如:

    when { expression { return params.DEBUG_BUILD } }
    
  • not 当嵌套条件是错误时,执行这个阶段,必须包含一个条件,例如:

    when { not { branch 'master' } }
    
  • allOf 当所有的嵌套条件都正确时,执行这个阶段,必须包含至少一个条件,例如:

    when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
    
  • anyOf 当至少有一个嵌套条件为真时,执行这个阶段,必须包含至少一个条件,例如:

    when { anyOf { branch 'master'; branch 'staging' } }
    
when使用示例
当参数test的值是123456时执行下载代码操作,即GetCode动作

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.10、parallel并行
	声明式流水线的阶段可以在他们内部声明多个嵌套阶段, 它们将并行执行。 
	注意,一个阶段必须只有一个 steps 或 parallel的阶段。 嵌套阶段本身不能包含 进一步的 parallel 阶段, 但是其他的阶段的行为与任何其他 stageparallel的阶段不能包含 agent 或 tools阶段, 因为他们没有相关 steps。
	另外, 通过添加 failFast true 到包含parallel的 stage中, 当其中一个进程失败时,你可以强制所有的 parallel 阶段都被终止
	
	如下示例:
		因为打包和扫描时间较长,将这两个操作添加到并行操作

在这里插入图片描述

总结

本篇文章主要针对常用的声明式Jenkinsfile流水线脚本的参数和框架做出了一个示例及简单的解释,因为平常接触和编写最多的就是声明式的流水线脚本。加油,开始练习写声明式流水线脚本吧,光看不练假把式~~~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python机器人Agent编程——实现一个本地大模型和爬虫结合的手机号归属地天气查询Agent

目录 一、前言二、准备工作三、Agent结构四、python模块实现4.1 实现手机号归属地查询工具4.2实现天气查询工具4.3定义创建Agent主体4.4创建聊天界面 五、小结PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源ps3.wifi小车控制相关…

uni-app打包后报错云服务空间未关联

使用uni-app打包到h5 项目里面用到了uni-app的云端一体城市选择组件&#xff0c;这个组件数据用到了uniCloud云服务空间&#xff0c;在本地运行没问题&#xff0c;打包之后测试环境报错&#xff1a; 一顿查&#xff0c;查到了官网是这样说的&#xff1a; cli publish --platfo…

SpringBoot框架:共享汽车行业的技术升级

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了共享汽车管理系统的开发全过程。通过分析共享汽车管理系统管理的不足&#xff0c;创建了一个计算机管理共享汽车管理系统的方案。文章介绍了共享汽车管理系统的系…

DBAPI连接阿里云 maxcompute 报错

使用正确的驱动包 访问以下链接寻找驱动包 https://github.com/aliyun/aliyun-odps-jdbc/releases/tag/v3.4.3 注意要使用odps-jdbc-3.4.3-jar-with-dependencies.jar &#xff0c;这个是完整的jar包 不要使用odps-jdbc-3.4.3.jar&#xff0c;这个不是完整的&#xff0c;它还…

【数据集】【YOLO】【目标检测】树木倒塌识别数据集 9957 张,YOLO道路树木断裂识别算法实战训练教程!

一、数据集介绍 【数据集】树木倒塌识别数据集 9957 张&#xff0c;目标检测&#xff0c;包含YOLO/VOC格式标注。 数据集中包含1种分类&#xff1a;{0: fallen_tree}&#xff0c;代表倒塌或者断裂的树木。 数据集来自国内外图片网站和视频截图&#xff1b; 可用于无人机树木…

贪心算法day2(最长递增子序列)

目录 1.最长递增子序列 方法一&#xff1a;动态规划 方法二&#xff1a;贪心二分查找 1.最长递增子序列 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 方法一&#xff1a;动态规划 思路&#xff1a;我们定义dp[i]为最长递增子序列&#xff0c;那么dp[j]就是…

基于微信小程序的电子购物系统的设计与实现(lw+演示+源码+运行)

摘 要 由于APP软件在开发以及运营上面所需成本较高&#xff0c;而用户手机需要安装各种APP软件&#xff0c;因此占用用户过多的手机存储空间&#xff0c;导致用户手机运行缓慢&#xff0c;体验度比较差&#xff0c;进而导致用户会卸载非必要的APP&#xff0c;倒逼管理者必须改…

雨晨 23H2 Windows 11 企业版 IE VCDX 适度 22631.4445 (VIP有限开放版本)

雨晨 23H2 Windows 11 企业版 IE VCDX 适度 22631.4445 &#xff08;VIP有限开放版本&#xff09; 文 件: 雨晨 23H2 Windows 11 企业版 适度 22631.4445 install.wim 提 取 码: ZZLR 大 小: 2824999564 字节 修改时间: 2024年11月9日, 星期六, 05:33:05 MD5 : 9C88…

OWASP TOP10 OSS 风险:开源软件安全指南

OWASP OSS 列表提供了旨在绕过 CVE 目录等滞后指标的建议&#xff0c;并为安全从业者提供了安全使用 OSS 组件的指南。 在最近的一些暴露的漏洞和风险之后&#xff0c;对开源软件 &#xff08;OSS&#xff09;的安全和使用方式进行批判性审视的呼声越来越高&#xff0c;特别是 …

无人机培训机型有哪些?CAAC考证选3类还是4类

无人机培训是一个涵盖多个方面的综合性过程&#xff0c;旨在培养具备无人机操作技能和相关知识的人才。 无人机培训机型 无人机培训通常涵盖多种机型&#xff0c;以满足不同领域和应用场景的需求。常见的无人机培训机型包括&#xff1a; 1. 多旋翼无人机&#xff1a;也称为多…

浏览器漫谈HTML--2.1印象深刻的标签-语义化标签

语义化标签 HTML语义化标签是HTML5引入的一个重要特性 常见的语义化标签&#xff1a; <header>, <nav>, <main>, <article>, <section>, <aside>, <footer> 布局如下 底层实现逻辑&&好处 语义化标签其实底层实现逻辑和…

el-table-column prop值根据数组获取

方法一&#xff1a; 可以给el-table-column添加一个属性&#xff1a;formatter&#xff0c;代码如下&#xff1a; 这里是因为多个列都需要同样的计算&#xff0c;所以使用column.property获取属性&#xff0c;不然可以直接row.属性 方法二&#xff1a; 直接在template scope …

2021-04-22 51单片机玩转点阵

理论就不赘述了,网络上多得很,直接从仿真软件感性上操作认识点阵,首先打开ISIS仿真软件,放置一个点阵和电源与地线就可以开始了;由点阵任何一脚连线到地线,另一边对应的引脚就连接到电源,如图:点击运行看是否点亮?看到蓝色与红色的点表示电源正常但是没有任何亮点,这时对调一下…

数据结构---详解单链表

一、单链表的概念及性质 1、链表的概念 链表是一种物理存储结构上非连续、非顺序的储存结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 我们看上图&#xff0c;一个链表就很像一节节车厢一样&#xff0c;和顺序表不同的是&#xff0c;链表里的每节“…

基于Spring Boot的网上商品订单转手系统设计与实现,LW+源码+讲解

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装网上商品订单转手系统软件来发挥其高效地信息处理的作用&a…

金蝶云星空与聚水潭系统的数据无缝对接案例

金蝶云星空与聚水潭的其他出库单数据集成案例分享 在企业日常运营中&#xff0c;数据的高效流动和准确处理至关重要。本文将重点介绍如何通过轻易云数据集成平台&#xff0c;实现金蝶云星空系统中的其他出库单数据无缝对接到聚水潭系统。本次集成方案名为“金蝶-其他出库单——…

企业级大数据安全架构

安全架构 一、集群访问控制1.1 Kerberos认证机制1.2 Apache Knox 统一访问网关 二、资源授权管理2.1 Apache Ranger 数据授权与管理 三、服务安全保障3.1 LDAP 轻量目录访问协议 四、大数据安全架构 当谈到企业级大数据平台时&#xff0c;安全性是一个至关重要的方面。随着数据…

cv::intersectConvexConvex返回其中一个输入点集,两个点集不相交

问题&#xff1a;cv::intersectConvexConvex返回其中一个输入点集&#xff0c;但两个点集并不相交 版本&#xff1a;opencv 3.1.0 git上也有人反馈了intersectConvexConvex sometimes returning one of the input polygons in case of empty intersection #10044 是凸包嵌套判…

贪心算法day3(最长递增序列问题)

目录 1.最长递增三元子序列 2.最长连续递增序列 1.最长递增三元子序列 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;我们只需要设置两个数进行比较就好。设a为nums[0]&#xff0c;b 为一个无穷大的数&#xff0c;只要有比a小的数字就赋值…

SpringBoot助力的共享汽车业务优化系统

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…