【打开新世界大门】看测试老鸟如何把API 测试玩弄在鼓掌之间

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程,刷完面试就稳了,你也可以当高薪软件测试工程师(自动化测试)

一、API 测试的基本步骤

我介绍过当今互联网产品的测试策略往往会采用菱形结构,即重量级 API 测试,轻量级 GUI 测试,轻量级单元测试,由此可见 API 测试在现今测试中的重要性不言而喻。这篇文章是 API 自动化测试系列的第一篇文章;

通常来讲,无论采用什么 API 测试工具,API 测试的基本步骤主要包括以下三大步骤:
1.准备测试数据(这是可选步骤,不一定所有 API 测试都需要这一步);
2.通过 API 测试工具,发起对被测 API 的 request;
3.验证返回结果的 response。

二、早期的基于 Postman 的 API 测试
早期的 API 测试,往往都是通过类似 Postman 的工具完成的。但是,由于这类工具都是基于界面操作的,所以有以下两个问题亟待解决:
当需要频繁执行大量的测试用例时,基于界面的 API 测试就显得有些笨拙;
基于界面操作的测试难以与 CI/CD 流水线集成。
所以,我们迫切需要一套可以基于命令行执行的 API 测试方案。
这样,API 测试可以直接通过命令行发起,与 CI/CD流水线的整合也就方便得多了。

三、基于 Postman 和 Newman 的 API 测试
于是就出现了集成 Postman 和 Newman 的方案,然后再结合 Jenkins 就可以很方便地实现 API 测试与 CI/CDl 流水线的集成。Newman 其实就是一个命令行工具,可以直接执行 Postman 导出的测试用例。

用 Postman 开发调试测试用例,完成后通过 Newman 执行,这个方案看似很完美。但是在实际工程实践中,测试场景除了简单调用单个 API 以外,还存在连续调用多个 API 的情况。

此时,往往会涉及到多个 API 调用时的数据传递问题,即下一个 API 调用的参数可能是上一个 API 调用返回结果中的某个值。另外,还会经常遇到的情况是,API 调用前需要先执行一些特定的操作,比如准备测试数据等。因此,对于需要连续调用多个 API 并且有参数传递的情况,Postman+Newman 似乎就不再是理想的测试方案了。

四、基于代码的 API 测试
为了解决这个问题,于是就出现了基于代码的 API 测试框架。比较典型的是,基于 Java 的 OkHttP 和 Unirest、基于 Python 的 http.client 和 Requests、基于 NodeJS 的 Native 和 Request 等。
小型的互联网企业,往往会根据自己的业务需求,选用这些成熟的 API 测试框架。

这种根据公司业务上下文开发实现的 API 测试框架,在使用上有很多优点,而且灵活性也很好,主要体现在以下几个方面:

可以灵活支持多个 API 的顺序调用,方便数据在多个 API 之间传递,即上一个 API 调用返回结果中的某个字段值可以作为后续 API 调用的输入参数;方便在 API 调用之前或者之后执行额外的任意操作,可以在调用前执行数据准备操作,可以在调用后执行现场清理工作等;可以很方便地支持数据驱动测试,这里的数据驱动测试概念和 GUI 测试中的数据驱动测试完全相同,也就是可以将测试数据和测试代码分离解耦;由于直接采用了代码实现,所以可以更灵活地处理测试验证的断言(Assert);原生支持命令行的测试执行方式,可以方便地和 CI/CD 工具做集成。

代码的第 1-12 行,创建了 CreateUserAPI 类,其中包含了 endpoint、操作方法 PUT、InlineParam 和 Param 的设置,并且构建了对应的 request 对象;代码的第 14-19 行,是测试的主体函数。这段函数的逻辑是这样的:首先,构建 CreateUserAPI 的对象;然后,用 CreateUserAPI 对象的 buildRequest 方法结合输入参数构建 request 对象;接着,通过 request 对象的 request() 方法发起了 API 调用;最后,验证 response 中的状态码是不是 200。

在这段伪代码中,有以下几点需要你特别注意:

代码中“CreateUserAPI 的父类 RestAPI”“_buildRequest() 方法”“request() 方法”“addInlineParam() 方法”等,都是由 API 测试框架提供的。为了简化代码,这里并没有引入数据驱动的 data provider。但在实际项目中,代码第 14 行的测试输入参数,往往来自于 data provider,即由数据驱动的方式提供测试输入数据。由于测试过程完全由代码实现,所以可以很方便的在测试执行前后增加任意的额外步骤。比如,需要在 CreateUser 前增加数据创建的步骤时,只需要在代码第 15 行前直接添加就可以了。这里的例子只有一个 API 调用,当需要多个 API 顺序调用时,直接扩展 testCreateUser 方法即可,两个 API 之间的数据传递可以通过上一个 API 返回的 response.XXXX 完成。通过这段伪代码,我们可以看到,虽然基于代码的 API 测试灵活性很好,也可以很方便地和 CI/CD 集成,但是也引入了一些新的问题,比如:对于单个 API 测试的场景,工作量相比 Postman 要大得多;对于单个 API 测试的场景,无法直接重用 Postman 里面已经积累的 Collection。在实际工程中,这两个问题非常重要,而且必须要解决。因为公司管理层肯定无法接受相同工作的工作量直线上升,同时原本已经完成的部分无法继续使用,所以自动化生成 API 测试代码的技术也就应运而生了。

五、自动生成 API 测试代码
测试中的断言(assert)部分不会生成代码,也就是说测试代码的生成只支持发起 request 的部分,而不会自动生成测试验证点的代码;很多中大型互联网企业都是使用自己开发的 API 测试框架,那么测试代码的实现就会和自研 API 测试框架绑定在一起,显然 Postman 并不支持这类代码的自动生成。鉴于以上两点,理想的做法是自己实现一个代码生成工具,这个工具的输入是 Postman 中 Collection 的 JSON 文件,输出是基于自研 API 框架的测试代码,而且同时会把测试的断言一并转化为代码。

这个小工具实现起来并不复杂,其本质就是解析 Collection JSON 文件的各个部分,然后根据自研 API 框架的代码模板实现变量替换。 具体来讲,实现过程大致可以分为以下三步:首先,根据自研 API 框架的代码结构建立一个带有变量占位符的模板文件;然后,通过 JSON 解析程序,按照 Collection JSON 文件的格式定义去提取 header、method 等信息;最后,用提取得到的具体值替换之前模板文件中的变量占位符,这样就得到了可执行的自研框架的 API 测试用例代码。有了这个工具后,我建议你的工作模式(Working Model)可以转换成这样:对于 Postman 中已经累积的 Collection,全部由这个工具统一转换成基于代码的 API 测试用例;开发人员继续使用 Postman 执行基本的测试,并将所有测试用例保存成 Collection,后续统一由工具转换成基于代码的 API 测试用例;对于复杂测试场景(比如,顺序调用多个 API 的测试),可以组装由工具转换得到的 API 测试用例代码,完成测试工作。

如图 2 所示,就是一个组装多个由工具转换得到的 API 测试用例代码的例子。其中,代码第 3 行的类“CreateUserAPI”和第 10 行的类“BindCreditCardAPI”的具体代码就可以通过工具转换得到。

至此,基于代码的 API 测试发展得算是比较成熟了,但在实际应用过程中还有一个痛点一直未被解决,那就是测试验证中的断言,也是我接下来要和你一起讨论的话题。

六、Response 结果发生变化时的自动识别
在实际的工程项目中,开发了大量的基于代码的 API 测试用例后,你会发现一个让人很纠结的问题:到底应该验证 API 返回结果中的哪些字段?
因为你不可能对返回结果中的每一个字段都写 assert,通常情况下:你只会针对关注的几个字段写 assert,而那些没写 assert 的字段也就无法被关注了。

但对 API 测试来说,有一个很重要的概念是后向兼容性(backward compatibility)。API 的后向兼容性是指,发布的新 API 版本应该能够兼容老版本的 API。后向兼容性除了要求 API 的调用参数不能发生变化外,还要求不能删减或者修改返回的 response 中的字段。因为这些返回的 response 会被下游的代码使用,如果字段被删减、改名或者字段值发生了非预期的变化,那么下游的代码就可能因为无法找到原本的字段,或者因为字段值的变化而发生问题,从而破坏 API 的后向兼容性。

        所以,我们迫切需要找到一个方法,既可以不对所有的 response 字段都去写 assert,又可以监测到 response 的结构以及没有写 assert 的字段值的变化。

        在这样的背景下,诞生了“Response 结果变化时的自动识别”技术。也就是说,即使我们没有针对每个 response 字段都去写 assert,我们仍然可以识别出哪些 response 字段发生了变化。

        具体实现的思路是,在 API 测试框架里引入一个内建数据库,推荐采用非关系型数据库(比如 MongoDB),然后用这个数据库记录每次调用的 request 和 response 的组合,当下次发送相同 request 时,API 测试框架就会自动和上次的 response 做差异检测,对于有变化的字段给出告警。

        你可能会说这种做法也有问题,因为有些字段的值每次 API 调用都是不同的,比如 token 值、session ID、时间戳等,这样每次的调用就都会有告警。

        但是这个问题很好解决,现在的解决办法是通过规则配置设立一个“白名单列表”,把那些动态值的字段排除在外

七、微服务模式下API测试要怎么做?
今天,我将更进一步,带你去了解当下最热门的技术领域的 API 测试,即微服务模式下的 API 测试。微服务架构下,API 测试的最大挑战来自于庞大的测试用例数量,以及微服务之间的相互耦合。所以,我今天分享这个主题的目的就是,帮你理解这两个问题的本质,以及如何基于消费者契约的方法来应对这两个难题。

而为了掌握微服务模式下的 API 测试,你需要先了解微服务架构(Microservice Architecture)的特点、测试挑战;而要了解微服务架构,你又需要先了解一些单体架构(Monolithic Architecture)的知识。所以,今天的话题我将逐层展开,目的就是希望你可以真正理解,并快速掌握微服务模式下的 API 测试。

单体架构(Monolithic Architecture)

单体架构是早期的架构模式,并且存在了很长时间。单体架构是将所有的业务场景的表示层、业务逻辑层和数据访问层放在同一个工程中,最终经过编译、打包,并部署在服务器上。比如,经典的 J2EE 工程,它就是将表示层的 JSP、业务逻辑层的 Service、Controller 和数据访问层的 DAO(Data Access Objects),打包成 war 文件,然后部署在 Tomcat、Jetty 或者其他 Servlet 容器中运行。

显然单体架构具有发布简单、方便调试、架构复杂性低等优点,所以长期以来一直被大量使用,并广泛应用于传统企业级软件。

    但是,随着互联网产品的普及,应用所承载的流量越来越庞大,单体架构的问题也被逐渐暴露并不断放大,主要的问题有以下几点:

1.灵活性差:无论是多小的修改,哪怕只修改了一行代码,也要打包发布整个应用。更糟的是,由于所有模块代码都在一起,所以每次编译打包都要花费很长时间。

2.可扩展性差:在高并发场景下,无法以模块为单位灵活扩展容量,不利于应用的横向扩展。

3.稳定性差:当单体应用中任何一个模块有问题时,都可能会造成应用整体的不可用,缺乏容错机制。

4.可维护性差:随着业务复杂性的提升,代码的复杂性也是直线上升,当业务规模比较庞大时,整体项目的可维护性会大打折扣

正是因为面对互联网应用时,单体架构有这一系列无法逾越的鸿沟,所以催生了微服务架构。

其实,微服务架构也不是一蹴而就的,也经历了很长时间的演化发展,中间还经历了著名的 SOA 架构。但是这个由单体架构到 SOA 架构再到微服务架构的演进过程,并不是本文的重点,所以我就不再详细展开了,如果你感兴趣的话,可以自行去查阅一些相关资料。

微服务架构(Microservice Architecture)

微服务是一种架构风格。在微服务架构下,一个大型复杂软件系统不再由一个单体组成,而是由一系列相互独立的微服务组成。其中,各个微服务运行在自己的进程中,开发和部署都没有依赖。

不同服务之间通过一些轻量级交互机制进行通信,例如 RPC、HTTP 等,服务可独立扩展伸缩,每个服务定义了明确的边界,只需要关注并很好地完成一件任务就可以了,不同的服务可以根据业务需求实现的便利性而采用不同的编程语言来实现,由独立的团队来维护。
图 1 就很形象地展示了单体架构和微服务架构之间的差异。

微服务架构具有以下特点:

每个服务运行在其独立的进程中,开发采用的技术栈也是独立的;
服务间采用轻量级通信机制进行沟通,通常是基于 HTTP 协议的 RESTful API;
每个服务都围绕着具体的业务进行构建,并且能够被独立开发、独立部署、独立发布;
对运维提出了非常高的要求,促进了 CI/CD 的发展与落地。

八、微服务架构下的测试挑战
由于微服务架构下,一个应用是由很多相互独立的微服务组成,每个微服务都会对外暴露接口,同时这些微服务之间存在级联调用关系,也就是说一个微服务通常还会去调用其他微服务,鉴于以上特点,微服务架构下的测试挑战主要来自于以下两个方面:
1.过于庞大的测试用例数量;
2.微服务之间的耦合关系。
接下来,我会针对这两项挑战分别展开,包括它们从何而来,以及如何应对这些挑战,最终完成测试。

第一,过于庞大的测试用例数量

1.在传统的 API 测试中,我们的测试策略通常是:

根据被测 API 输入参数的各种组合调用API,并验证相关结果的正确性;
2.衡量上述测试过程的代码覆盖率;
3.根据代码覆盖率进一步找出遗漏的测试用例;
4.以代码覆盖率达标作为 API 测试成功完成的标志。
这也是单体架构时代主流的 API 测试策略。为了让你更好地理解这种测试策略,我来举一个实际的例子。

假设我们采用单体架构开发了一个系统,这个系统对外提供了 3 个 Restful API 接口,那么我们的测试策略应该是:

针对这 3 个 API 接口,分别基于边界值和等价类方法设计测试用例并执行;
2.在测试执行过程中,启用代码覆盖率统计;
3.假设测试完成后代码行覆盖率是 80%,那么我们就需要找到那些还没有被执行到的 20% 的代码行。比如图 2 中代码的第 242 行就是没有被执行到,分析代码逻辑后发现,我们需要构造“expected!=actual”才能覆盖这个未能执行的代码行;
3.最终我们要保证代码覆盖率达到既定的要求,比如行覆盖率达到 100%,完成 API 测试。


而当我们采用微服务架构时,原本的单体应用会被拆分成多个独立模块,也就是很多个独立的 service,原本单体应用的全局功能将会由这些拆分得到的 API 共同协作完成。
比如,对于上面这个例子,没有微服务化之前,一共有 3 个 API 接口,假定现在采用微服务架构,该系统被拆分成了 10 个独立的 service,如果每个 service 平均对外暴露 3 个 API 接口,那么总共需要测试的 API 接口数量就多达 30 个。
如果我还按照传统的 API 测试策略来测试这些 API,那么测试用例的数量就会非常多,过多的测试用例往往就需要耗费大量的测试执行时间和资源。

 但是,在互联网模式下,产品发布的周期往往是以“天”甚至是以“小时”为单位的,留给测试的执行时间非常有限,所以微服务化后 API 测试用例数量的显著增长就对测试发起了巨大的挑战。

 这时,我们迫切需要找到一种既能保证 API 质量,又能减少测试用例数量的测试策略,这也就是我接下来要分享的基于消费者契约的 API 测试。

九、第二,微服务之间的耦合关系
微服务化后,服务与服务间的依赖也可能会给测试带来不小的挑战。
如图 3 所示,假定我们的被测对象是 Service T,但是 Service T 的内部又调用了 Service X 和 Service Y。此时,如果 Service X 和 Service Y 由于各种原因处于不可用的状态,那么此时就无法对 Service T 进行完整的测试。

我们迫切需要一种方法可以将 Service T 的测试与 Service X 和 Service Y 解耦
解耦的方式通常就是实现 Mock Service 来代替被依赖的真实 Service。实现这个 Mock Service 的关键点就是要能够模拟真实 Service 的 Request 和 Response。当我介绍完基于消费者契约的 API 测试后,你会发现这个问题也就迎刃而解了。

十、基于消费者契约的 API 测试
那到底什么是基于消费者契约的 API 测试呢?直接从概念的角度解释,会有些难以理解。所以我打算换个方法来帮助你从本质上真正理解什么是基于消费者契约的 API 测试。接下来,就跟着我的思路走吧。

首先,我们来看图 4,假设图 4 中的 Service A、Service B 和 Service T 是微服务拆分后的三个 Service,其中 Service T 是被测试对象,进一步假定 Service T 的消费者(也就是使用者)一共有两个,分别是 Service A 和 Service B。

按照传统的 API 测试策略,当我们需要测试 Service T 时,需要找到所有可能的参数组合依次对 Service T 进行调用,同时结合 Service T 的代码覆盖率进一步补充遗漏的测试用例。

这种思路本身没有任何问题,但是测试用例的数量会非常多。那我们就需要思考,如何既能保证 Service T 的质量,又不需要覆盖全部可能的测试用例。

静下心来想一下,你会发现 Service T 的使用者是确定的,只有 Service A 和 Service B,如果可以把 Service A 和 Service B 对 Service T 所有可能的调用方式都测试到,那么就一定可以保证 Service T 的质量。即使存在某些 Service T 的其他调用方式有出错的可能性,那也不会影响整个系统的功能,因为这个系统中并没有其他 Service 会以这种可能出错的方式来调用 Service T。
现在,问题就转化成了如何找到 Service A 和 Service B 对 Service T 所有可能的调用方式。如果能够找出这样的调用集合,并以此作为 Service T 的测试用例,那么只要这些测试用例 100% 通过,Service T 的质量也就不在话下了。
本质上来讲,这样的测试用例集合其实就是,Service T 可以对外提供的服务的契约,所以我们把这个测试用例的集合称为“基于消费者契约的 API 测试”。
那么接下来,我们要解决的问题就是:如何才能找到 Service A 和 Service B 对 Service T 的所有可能调用了。其实这也很简单,在逻辑结构上,我们只要在 Service T 前放置一个代理,所有进出 Service T 的 Request 和 Response 都会经过这个代理,并被记录成 JSON 文件,也就构成了 Service T 的契约。

在实际项目中,我们不可能在每个 Service 前去放置这样一个代理。但是,微服务架构中往往会存在一个叫作 API Gateway 的组件,用于记录所有 API 之间相互调用关系的日志,我们可以通过解析 API Gateway 的日志分析得到每个 Service 的契约。
至此,我们已经清楚地知道了如何获取 Service 的契约,并由此来构成 Service 的契约测试用例。接下来,就是如何解决微服务之间耦合关系带来的问题了。

十一、微服务测试的依赖解耦和 Mock Service
实现 Mock Service 的关键,就是要能够模拟被替代 Service 的 Request 和 Response。
时我们已经拿到了契约,契约的本质就是 Request 和 Response 的组合,具体的表现形式往往是 JSON 文件,此时我们就可以用该契约的 JSON 文件作为 Mock Service 的依据,也就是在收到什么 Request 的时候应该回复什么 Response。
下面的图 6 就解释了这一关系,当用 Service X 的契约启动 Mock Service X 后,原本真实的 Service X 将被 Mock Service X 替代,也就解耦了服务之间的依赖,图 6 中的 Service Y 也是一样的道理。

  下面是配套学习资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

 

文档获取方式:

这份文档,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

以上均可以分享,只需要你搜索vx公众号:程序员雨果,即可免费领取

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

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

相关文章

领跑物联网芯片市场|乐鑫 IoT 芯片全球出货量突破 10 亿颗!

乐鑫科技 (688018.SH) 高兴地宣布,其物联网芯片全球累计出货量已突破 10 亿颗。这一里程碑标志着乐鑫作为全球领先的物联网软硬件和解决方案提供商,以其创新的前沿技术和卓越的产品性能,赢得了全球市场的认可,奠定了其在物联网无线…

华为云HECS安装docker

1、运行安装指令 yum install docker都选择y,直到安装成功 2、查看是否安装成功 运行版本查看指令,显示docker版本,证明安装成功 docker --version 或者 docker -v 3、启用并运行docker 3.1启用docker 指令 systemctl enable docker …

STM32单片机中国象棋TFT触摸屏小游戏

实践制作DIY- GC0167-中国象棋 一、功能说明: 基于STM32单片机设计-中国象棋 二、功能介绍: 硬件组成:STM32F103RCT6最小系统2.8寸TFT电阻触摸屏24C02存储器1个按键(悔棋) 游戏规则: 1.有悔棋键&…

Unity截图生成图片 图片生成器 一键生成图片

使用Unity编辑器扩展技术实现快速截图功能 效果: 里面没有什么太难的技术,直接上源码吧 注意!代码需要放在Editor文件下才能正常运行 using System; using UnityEditor; using UnityEngine;[ExecuteInEditMode] public class Screenshot …

软件需求文档、设计文档、开发文档、运维文档大全

在软件开发过程中,文档扮演着至关重要的角色。它不仅记录了项目的需求、设计和开发过程,还为项目的维护和管理提供了便利。本文将详细介绍软件开发文档的重要性和作用,以及需求分析、软件设计、开发过程、运维管理和项目管理等方面的文档要求…

LinkedList相较于Arravlist的特点/优化

Arravlist底层是内存空间连续的数组,可以根据下标进行随机访问,效率比较高,因为在根据下标访问某一个元素时,并不是一个一个去查,而是算出来这个下标的地址,直接根据这个地址的指向去获取的,因为…

MATLAB实现相关性分析

目录 一.基本理论 二.两类相关系数的对比 三.相关系数的假设检验 四.MATLAB的相关操作 五.其他有关的一些列技巧 六.案例展示 七.实战操作 一.基本理论 所谓相关系数,本质上是来衡量两组数据的关系大小——对应呈现函数关心的两种变量,那么我们可以…

[NLP] LLM---<训练中文LLama2(四)方式一>对LLama2进行SFT微调

指令精调 指令精调阶段的任务形式基本与Stanford Alpaca相同。训练方案也采用了LoRA进行高效精调,并进一步增加了可训练参数数量。在prompt设计上,精调以及预测时采用的都是原版Stanford Alpaca不带input的模版。对于包含input字段的数据,采…

计算机视觉与深度学习-卷积神经网络-卷积图像去噪边缘提取-图像去噪 [北邮鲁鹏]

目录标题 参考学习链接图像噪声噪声分类椒盐噪声脉冲噪声对椒盐噪声&脉冲噪声去噪使用高斯卷积核中值滤波器 高斯噪声减少高斯噪声 参考学习链接 计算机视觉与深度学习-04-图像去噪&卷积-北邮鲁鹏老师课程笔记 图像噪声 噪声点,其实在视觉上看上去让人感…

新建WinForm工程以及添加log

本篇博客将介绍如何使用Visual Studio新建一个WinForm工程,由于我还不知道有什么实时地看到程序输出的方法(调试当然是一个好方法),因此参照同事的代码, 加入了一个输出log的功能。 一、新建一个WinForm工程&#xff…

2023年中国研究生数学建模竞赛D题解题思路

为了更好的帮助大家第一天选题,这里首先为大家带来D题解题思路,分析对应赛题之后做题阶段可能会遇到的各种难点。 稍后会带来D题的详细解析思路,以及相关的其他版本解题思路 成品论文等资料。 赛题难度评估:A、B>C>E、F&g…

腾讯面试题:无网络环境,如何部署Docker镜像?

亲爱的小伙伴们,大家好!我是小米,很高兴再次和大家见面。今天,我要和大家聊聊一个特别有趣的话题——腾讯面试题:无网络环境,如何部署Docker镜像?这可是一个技术含量颇高的问题哦!废…

Mybatis SQL构建器

上一篇我们介绍了在Mybatis映射器中使用SelectProvider、InsertProvider、UpdateProvider、DeleteProvider进行对数据的增删改查操作;本篇我们介绍如何使用SQL构建器在Provider中优雅的构建SQL语句。 如果您对在Mybatis映射器中使用SelectProvider、InsertProvider…

启山智软/一款包含主流商城类型的一款电商中台系统100%开源

文章目录 介绍一、Smart Shop JAVA 微服务电商中台优势二、电商中台包含那些主流商城模式1.S2B2C供应链商城2.B2B2C多商户商城3.B2C单商户商城4.O2O外卖配送商城5.社区团购商城 6.演示地址总结 介绍 想要了解代码规范,学习商城解决方案,点击下方官网链接…

【PHP图片托管】CFimagehost搭建私人图床 - 无需数据库支持

文章目录 1.前言2. CFImagehost网站搭建2.1 CFImagehost下载和安装2.2 CFImagehost网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道(云端设置)3.3.Cpolar稳定隧道(本地设置) 4.公网访问测…

【10个OOM异常的场景以及对应的排查经验】

文章目录 1. 场景描述:内存泄漏2. 场景描述:过多线程3. 场景描述:大量数据查询4. 场景描述:大文件读取5. 场景描述:高并发访问6. 场景描述:大字符串操作7. 场景描述:大数据集合操作8. 场景描述&…

Stable Diffusion WebUI插件posex安装以及无法使用完美解决办法汇总

posex是一个很好用的3Dopenpose编辑器。 我们只需要去官网找到源码就可以查看其用法。 对于安装大家应该都知道怎么去安装。 1. 如何安装 (1)一体包安装方式 类似于秋叶一体包直接在webui界面搜索posex就可以直接install。 最新版本好像已经取消了。 (2)手动安装方式…

婚礼策划展示小程序制作全程解析

随着互联网的发展,小程序已成为各行各业所钟爱的一种数字化工具。对于婚礼策划师来说,一款专为自己业务打造的小程序能够更好地展示婚礼策划方案,提升服务质量,加强与客户的沟通。以下就是制作婚礼策划展示小程序的全程解析。 一、…

链表oj3(Leetcode)——相交链表;环形链表

一,相交链表 相交链表(Leetcode) 1.1分析 看到这个我们首先想到的就是一个一个比较他们的值有相等的就是交点,但是如果a1和b2的值就相等呢?所以这个思路不行,第二种就是依次比较链表,但是这…

redis漏洞修复:(CNVD-2019-21763)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、漏洞内容二、镜像准备1.确认镜像版本2.下载镜像 三、配置文件准备1.获取配置文件2.修改配置文件 四、启动redis容器五、修改iptables文件总结 前言 漏扫发…