dbunit使用_摆脱困境:在DbUnit数据集中使用空值

dbunit使用

如果我们正在为使用Spring Framework的应用程序编写集成测试,则可以通过使用Spring Test DbUnit将DbUnit与Spring测试框架集成。

但是, 这种集成并非没有问题

通常,我们必须在运行测试之前向数据库中插入值,或者验证保存到特定表列中的是否为 。 这些是非常基本的用例,但是编写支持它们的集成测试非常棘手。

这篇博客文章指出了与值有关的问题,并描述了如何解决它们。 让我们从快速查看被测系统开始。

如果您不知道如何为存储库编写集成测试,则应阅读我的博客文章,标题为: Spring Data JPA教程:集成测试 。

它说明了如何为Spring Data JPA存储库编写集成测试,但是您可以使用相同的方法为其他使用关系数据库的Spring支持的存储库编写测试。

被测系统

经过测试的“应用程序”具有一个实体和一个Spring Data JPA存储库,该存储库为该实体提供CRUD操作。

我们的实体类称为Todo ,其源代码的相关部分如下所示:

import javax.persistence.*;@Entity
@Table(name="todos")
public class Todo {private static final int MAX_LENGTH_DESCRIPTION = 500;private static final int MAX_LENGTH_TITLE = 100;@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;@Column(name = "description", nullable = true, length = MAX_LENGTH_DESCRIPTION)private String description;@Column(name = "title", nullable = false, length = MAX_LENGTH_TITLE)private String title;@Versionprivate long version;//Constructors, builder class, and getters are omitted.
}
  • 您可以从Github获取Todo类的完整源代码 。

另外,我们不应该使用构建器模式,因为在创建新的Todo对象时,我们的实体只有两个String字段被设置。 但是,我在这里使用它是因为它使我们的测试更易于阅读。

我们的Spring Data JPA存储库接口称为TodoRepository ,它扩展了CrudRepository <T,ID扩展了Serializable>接口。 该存储库为Todo对象提供CRUD操作。 它还声明了一种查询方法,该方法返回其说明与给定搜索词匹配的所有待办事项条目。

TodoRepository接口的源代码如下所示:

import org.springframework.data.repository.CrudRepository;public interface TodoRepository extends CrudRepository<Todo, Long> {List<Todo> findByDescription(String description);
}

补充阅读:

  • CrudRepository接口的Javadoc
  • Spring Data JPA教程
  • Spring Data JPA –参考文档

让我们继续前进,了解在编写用于从关系数据库读取信息或将信息保存到其中的代码的集成测试时,如何处理值。

处理空值

在为数据访问代码编写集成测试时 ,我们必须在每个测试用例之前将数据库初始化为已知状态,并确保将正确的数据写入数据库。

本节确定了在编写集成测试以解决我们遇到的问题

  • 使用平面XML数据集。
  • 值写入数据库,或确保表列的值为null

我们还将学习如何解决这些问题。

将空值插入数据库

当我们编写从数据库读取信息的集成测试时,我们必须在调用测试之前将该数据库初始化为已知状态,有时我们必须向数据库中插入值。

因为我们使用平面XML数据集,所以可以通过省略相应的属性值将值插入表列。 这意味着,如果我们想在todos表的description列中插入值,则可以使用以下DbUnit数据集来做到这一点:

<dataset><todos id="1" title="FooBar" version="0"/>
</dataset>

但是,通常我们必须在已使用的数据库表中插入多行。 以下DbUnit数据集( todo-entries.xml )将两行插入todos表:

<dataset><todos id="1" title="FooBar" version="0"/><todos id="2" description="description" title="title" version="0"/>
</dataset>

让我们找出对TodoRepository接口的findByDescription()方法编写集成测试并使用先前的数据集( todo-entries.xml )初始化数据库时会发生什么情况。 我们的集成测试的源代码如下所示:

import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;import static org.assertj.core.api.Assertions.assertThat;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceContext.class})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,DirtiesContextTestExecutionListener.class,TransactionalTestExecutionListener.class,DbUnitTestExecutionListener.class })
public class ITTodoRepositoryTest {private static final Long ID = 2L;private static final String DESCRIPTION = "description";private static final String TITLE = "title";private static final long VERSION = 0L;@Autowiredprivate TodoRepository repository;@Test@DatabaseSetup("todo-entries.xml")public void findByDescription_ShouldReturnOneTodoEntry() {List<Todo> todoEntries = repository.findByDescription(DESCRIPTION);assertThat(todoEntries).hasSize(1);Todo found = todoEntries.get(0);assertThat(found.getId()).isEqualTo(ID);assertThat(found.getTitle()).isEqualTo(TITLE);assertThat(found.getDescription()).isEqualTo(DESCRIPTION);assertThat(found.getVersion()).isEqualTo(VERSION);}
}

当运行此集成测试时,我们得到以下断言错误:

java.lang.AssertionError: 
Expected size:<1> but was:<0> in: <[]>

这意味着从数据库中找不到正确的待办事项条目。 发生了什么? 我们的查询方法是如此简单,以至于它应该起作用,特别是因为在调用测试用例之前,我们已将正确的数据插入数据库。

好吧,实际上两行的描述列都是空的。 DbUnit常见问题说明了发生这种情况的原因 :

DbUnit使用表的第一个标记来定义要填充的列。 如果此表的以下记录包含额外的列,那么将不会填充这些列。

它还提供了解决此问题的方法:

从DBUnit 2.3.0开始,有一种称为“列感知”的功能,该功能基本上将整个XML读入缓冲区,并在出现新列时动态添加它们。

我们可以通过反转todos元素的顺序来解决此问题,但这很麻烦,因为每次创建新数据集时我们都必须记住要做的事情。 我们应该使用列检测,因为它消除了人为错误的可能性。

我们可以按照以下步骤启用列检测:

  1. 创建一个扩展了AbstractDataSetLoader类的数据集加载器类。
  2. 重写AbstractDataSetLoader类的受保护的IDateSet createDataSet(Resource resource)方法。
  3. 通过启用列检测并返回新的FlatXmlDataSet对象来实现此方法。

ColumnSensingFlatXmlDataSetLoader类的源代码如下所示:

import com.github.springtestdbunit.dataset.AbstractDataSetLoader;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.springframework.core.io.Resource;
import java.io.InputStream;public class ColumnSensingFlatXMLDataSetLoader extends AbstractDataSetLoader {@Overrideprotected IDataSet createDataSet(Resource resource) throws Exception {FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();builder.setColumnSensing(true);try (InputStream inputStream = resource.getInputStream()) {return builder.build(inputStream);}}
}

补充阅读:

  • FlatXmlDataSet类的Javadoc

现在,我们可以通过使用@DbUnitConfiguration批注注释测试类并将其加载器属性的值设置为ColumnSensingFlatXmlDataSetLoader.class,来配置测试类以使用此数据加载

我们的固定集成测试的源代码如下所示:

import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;import static org.assertj.core.api.Assertions.assertThat;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceContext.class})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,DirtiesContextTestExecutionListener.class,TransactionalTestExecutionListener.class,DbUnitTestExecutionListener.class })
@DbUnitConfiguration(dataSetLoader = ColumnSensingFlatXMLDataSetLoader.class)
public class ITTodoRepositoryTest {private static final Long ID = 2L;private static final String DESCRIPTION = "description";private static final String TITLE = "title";private static final long VERSION = 0L;@Autowiredprivate TodoRepository repository;@Test@DatabaseSetup("todo-entries.xml")public void findByDescription_ShouldReturnOneTodoEntry() {List<Todo> todoEntries = repository.findByDescription(DESCRIPTION);assertThat(todoEntries).hasSize(1);Todo found = todoEntries.get(0);assertThat(found.getId()).isEqualTo(ID);assertThat(found.getTitle()).isEqualTo(TITLE);assertThat(found.getDescription()).isEqualTo(DESCRIPTION);assertThat(found.getVersion()).isEqualTo(VERSION);}
}

当我们第二次运行集成测试时,它通过了。

让我们找出如何验证值是否已保存到数据库中。

验证表列的值是否为空

在编写将信息保存到数据库的集成测试时,我们必须确保将正确的信息确实保存到数据库,有时我们必须验证表列的值为null

例如,如果我们写这证实了,当我们创建一个没有描述一个待办事项条目正确的信息保存到数据库中的集成测试,我们必须确保一个值插入到待办事项表的说明列。

我们的集成测试的源代码如下所示:

import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;import static org.assertj.core.api.Assertions.assertThat;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceContext.class})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,DirtiesContextTestExecutionListener.class,TransactionalTestExecutionListener.class,DbUnitTestExecutionListener.class })
@DbUnitConfiguration(dataSetLoader = ColumnSensingFlatXMLDataSetLoader.class)
public class ITTodoRepositoryTest {private static final String DESCRIPTION = "description";private static final String TITLE = "title";@Autowiredprivate TodoRepository repository;@Test@DatabaseSetup("no-todo-entries.xml")@ExpectedDatabase("save-todo-entry-without-description-expected.xml")public void save_WithoutDescription_ShouldSaveTodoEntryToDatabase() {Todo todoEntry = Todo.getBuilder().title(TITLE).description(null).build();repository.save(todoEntry);}
}

这不是一个很好的集成测试,因为它仅测试Spring Data JPA和Hibernate是否正常工作。 我们不应该通过为框架编写测试来浪费时间。 如果我们不信任框架,则不应使用它。

如果您想学习为数据访问代码编写好的集成测试,则应该阅读标题为: 编写数据访问代码测试的教程。

用于初始化数据库的DbUnit数据集( no-todo-entries.xml )如下所示:

<dataset><todos/>
</dataset>

因为我们没有设置保存的todo条目的描述 ,所以todos表的description列应该为null 。 这意味着我们应该从数据集中省略它,以验证是否将正确的信息保存到数据库中。

该数据集( save-todo-entry-without-description-expected.xml )如下所示:

<dataset><todos id="1" title="title" version="0"/>
</dataset>

当我们运行集成测试时,它失败,并且我们看到以下错误消息:

junit.framework.ComparisonFailure: column count (table=todos, expectedColCount=3, actualColCount=4) 
Expected :[id, title, version]
Actual   :[DESCRIPTION, ID, TITLE, VERSION]

问题在于DbUnit期望todos表仅具有idtitleversion列。 这样做的原因是,这些列是从数据集的第一行(也是唯一的行)中找到的唯一列。

我们可以使用ReplacementDataSet解决此问题。 ReplacementDataSet是一个修饰器,它用替换对象替换从平面XML数据集文件中找到的占位符。 让我们修改自定义的数据集加载类返回一个ReplacementDataSet对象替换“[空]”字符串与

我们可以通过对自定义数据集加载器进行以下更改来做到这一点:

  1. 私有的createReplacementDataSet()方法添加到数据集加载器类。 此方法返回一个ReplacementDataSet对象,并采用FlatXmlDataSet对象作为方法参数。
  2. 通过创建新的ReplacementDataSet对象并返回创建的对象来实现此方法。
  3. 修改createDataSet()方法以调用私有的createReplacementDataSet()方法并返回创建的ReplacementDataSet对象。

ColumnSensingReplacementDataSetLoader类的源代码如下所示:

import com.github.springtestdbunit.dataset.AbstractDataSetLoader;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ReplacementDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.springframework.core.io.Resource;import java.io.InputStream;public class ColumnSensingReplacementDataSetLoader extends AbstractDataSetLoader {@Overrideprotected IDataSet createDataSet(Resource resource) throws Exception {FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();builder.setColumnSensing(true);try (InputStream inputStream = resource.getInputStream()) {return createReplacementDataSet(builder.build(inputStream));}}private ReplacementDataSet createReplacementDataSet(FlatXmlDataSet dataSet) {ReplacementDataSet replacementDataSet = new ReplacementDataSet(dataSet);//Configure the replacement dataset to replace '[null]' strings with null.replacementDataSet.addReplacementObject("[null]", null);return replacementDataSet;}
}

补充阅读:

  • IDataSet接口的最常用实现
  • ReplacementDataSet类的Javadoc

我们可以按照以下步骤修复集成测试:

  1. 通过使用ColumnSensingReplacementDataSetLoader类,配置我们的测试类以加载使用的DbUnit数据集。
  2. 修改我们的数据集以验证description列的值为null

首先 ,我们必须配置测试类以使用ColumnSensingReplacementDataSetLoader类加载DbUnit数据集。 因为我们已经使用@DbUnitConfiguration注释了测试类,所以我们必须将其loader属性的值更改为ColumnSensingReplacementDataSetLoader.class

固定测试类的源代码如下所示:

import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;import static org.assertj.core.api.Assertions.assertThat;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceContext.class})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,DirtiesContextTestExecutionListener.class,TransactionalTestExecutionListener.class,DbUnitTestExecutionListener.class })
@DbUnitConfiguration(dataSetLoader = ColumnSensingReplacementDataSetLoader.class)
public class ITTodoRepositoryTest {private static final String DESCRIPTION = "description";private static final String TITLE = "title";@Autowiredprivate TodoRepository repository;@Test@DatabaseSetup("no-todo-entries.xml")@ExpectedDatabase("save-todo-entry-without-description-expected.xml")public void save_WithoutDescription_ShouldSaveTodoEntryToDatabase() {Todo todoEntry = Todo.getBuilder().title(TITLE).description(null).build();repository.save(todoEntry);}
}

其次 ,我们必须验证null值是否保存到todos表的description列中。 为此,我们可以向数据集中唯一的todos元素添加一个description属性,并将description属性的值设置为'[null]'。

我们的固定数据集( save-todo-entry-without-description-expected.xml )如下所示:

<dataset><todos id="1" description="[null]" title="title" version="0"/>
</dataset>

当我们运行集成测试时,它会通过。

让我们继续并总结从这篇博客文章中学到的知识。

摘要

这篇博客文章教会了我们四件事:

  • DbUnit假定数据库表仅包含从指定表行的列的第一个标记中找到的那些列。 如果要覆盖此行为,则必须启用DbUnit的列感测功能。
  • 如果要确保将null值保存到数据库,则必须使用替换数据集。
  • 我们学习了如何创建自定义数据集加载器,以创建替换数据集并使用列感测。
  • 我们了解了如何配置用于加载DbUnit数据集的数据集加载器。

您可以从Github获得此博客文章的示例应用程序 。

翻译自: https://www.javacodegeeks.com/2014/11/spring-from-the-trenches-using-null-values-in-dbunit-datasets.html

dbunit使用

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

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

相关文章

android汉字田字格,画一个简单的田字格

image.png上代码package com.nick.customview;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.support.annotation.Nullable;import android.sup…

xp定时关机软件_好用又免费的电脑定时工具,不用得后悔

现在利用电脑办公的人有多少&#xff0c;举个手示意下&#xff01;&#xff01;&#xff01;给电脑设置定时关机&#xff0c;可以方便我们不在电脑前完成关机操作。那么&#xff0c;如何设置定时关机呢&#xff1f;如果要取消&#xff0c;定时关机又如何取消&#xff1f;有的人…

apache camel_Apache Camel请向我解释这些端点选项的含义

apache camel在即将发布的Apache Camel 2.15中&#xff0c;我们使Camel更智能。 现在&#xff0c;它可以充当老师&#xff0c;并向您说明其配置方式以及这些选项的含义。 Camel可以做的第一课是告诉您如何配置所有端点以及这些选项的含义。 接下来我们要学习的课程是让Camel解…

android照片备份软件下载,照片备份云相册app下载-照片备份云相册下载V1.9安卓版-西西软件下载...

这款软件主要为安卓手机用户提供照片图片等备份的服务&#xff0c;通过照片备份云相册app可以轻松的为更多手机空间不够的用户清理出手机空间&#xff0c;照片图片等的是最不容易发现占用空间的&#xff0c;现在有了照片备份云相册app就能轻松让手机内存足够使用哦。照片备份云…

手机照片导入电脑步骤_如何将手机中的照片、视频快速的保存到U盘上?3分钟教你详细步骤...

手机拍照功能是越来越强大了。生活中&#xff0c;不少的朋友都喜欢拍照。拍着拍着不知不觉就存了许多的照片&#xff0c;占用很大的空间。手机照片和视频都是我们非常重要的回忆&#xff0c;许多人都不愿意删除。为了节省我们手机的空间&#xff0c;许多人都会选择将手机照片导…

筒仓计算表格_身份反模式:联邦筒仓和意大利面条身份

筒仓计算表格分析公司Quocirca的最新研究证实&#xff0c;现在许多企业的外部用户比内部用户更多&#xff1a;在欧洲&#xff0c;有58&#xff05;的企业直接与其他企业和/或消费者的用户进行交易&#xff1b; 仅在英国&#xff0c;这一数字就达到了65&#xff05;。 如果回顾历…

C/C 宏替换详解

1. 基本形式#define name replacement_text 复制代码通常情况下&#xff0c;#define 指令占一行&#xff0c;替换文本是 define 指令行尾部的所有剩余部分&#xff0c;但也可以把一个较长的宏定义分成若干行&#xff0c;这时需要在待续的行末尾加上一个反斜杠符 。宏定义也可以…

android webview 设置文字颜色,android webView 修改页面字体颜色

webview加载一个界面后&#xff0c;在onPageFinished中加入修改页面字体颜色css&#xff0c;如下String nightCode "";try {InputStream is getResources().openRawResource(R.raw.day);byte[] buffer;buffer new byte[is.available()];is.read(buffer);is.close(…

win10更新助手_快升级!win10精简版不到10G,比win7还干净流畅,无需更新!

在整个PC端操作系统中&#xff0c;最成功的得主自然要说微软。毕竟微软发布的XP、win7操作系统那可是风靡全球&#xff0c;占用的用户资源十分庞大。单单因为这两个操作系统就吸引到了足够的用户&#xff0c;整个装机下载量可真不是盖的&#xff0c;说微软是PC端的"老大&q…

openshift命令_使用命令行工具创建WildFly OpenShift应用程序

openshift命令通过使用快速入门&#xff0c;可以轻松地在OpenShift上配置WildFly的新实例。 只需单击一下&#xff0c;您就可以准备就绪&#xff01; 通常&#xff0c;OpenShift的高级用户使用命令行工具 。 但是&#xff0c;您无法使用CLI工具创建WildFly墨盒。 但现在已解决…

android 加解密的速度和什么有关系,Android 加解密类Cipher

近日在做一个关于短信及文件加解密的小项目&#xff0c;查看了一些Android加解密方面的知识。关于加解密这部分以前完全没有接触过&#xff0c;所以网上乱翻了一天对于什么DES&#xff0c;AES&#xff0c;RSA&#xff0c;BASE64&#xff0c;MD5之类的还是懵懵懂懂&#xff0c;这…

redis缓存原理与实现_SpringBoot整合Redis缓存,手把手教你一步一步实现

推荐学习分布式大全&#xff1a;反向代理/Redis/中间件/MySQL/消息&#xff0c;挑战阿里P7必备都是“Redis惹的祸”&#xff0c;害我差点挂在美团三面&#xff0c;真是“虚惊一场”微服务架构之春招总结&#xff1a;SpringCloud、Docker、Dubbo与SpringBoot一、基本概况为什么使…

C 实现高性能内存池

版权一、概述在 C/C 中&#xff0c;内存管理是一个非常棘手的问题&#xff0c;我们在编写一个程序的时候几乎不可避免的要遇到内存的分配逻辑&#xff0c;这时候随之而来的有这样一些问题&#xff1a;是否有足够的内存可供分配? 分配失败了怎么办? 如何管理自身的内存使用情况…

【计算理论】06 可归约性

文章目录 本章要点可归约性映射可归约图灵可判定归约证明 H A L T T M HALT_{TM} HALTTM​不可判定 E T M E_{TM} ETM​不可判定 R E G U L A R T M REGULAR_{TM} REGULARTM​不可判定 E Q T M EQ_{TM} EQTM​不可判定 图灵可识别的归约性参考 本章要点 可归约性定义&#xff…

组件注入 # 注入的属性_注入域对象而不是基础结构组件

组件注入 # 注入的属性依赖注入是Java&#xff08;以及许多其他编程语言&#xff09;中广泛使用的软件设计模式&#xff0c;用于实现控制反转 。 它提高了可重用性&#xff0c;可测试性&#xff0c;可维护性&#xff0c;并有助于构建松耦合的组件。 如今&#xff0c;依赖注入是…

docker $PWD路径_Docker安装Jenkins+Shell脚本自动化部署项目

本文同名博客老炮说Java&#xff1a;https://www.laopaojava.com/&#xff0c;每天更新Spring/SpringMvc/SpringBoot/实战项目等文章资料SentinelNacos 是微服务环境搭建必不可少的两个组件&#xff0c;这里给大家推荐一套微服务教程&#xff1a;SpringCloud微服务电商项目教程…

flyme Android7.0 root,手把手教你如何免ROOT卸载Flyme7系统自带APP

本教程需要使用adb&#xff0c;adb的全称为Android Debug bridge&#xff0c;就是起到调试桥的作用。借助adb工具&#xff0c;我们可以管理设备或手机模拟器的状态。本教程需要使用adb&#xff0c;adb的全称为Android Debug bridge&#xff0c;就是起到调试桥的作用。借助adb工…

C语言 -- 字符串中根据特定字符(串)分割

版权C语言字符串操作函数有很多&#xff0c;这里举出需要用到的&#xff0c;其他请自行查找。1、len strlen(p) &#xff1b;//取字符串长度 原型&#xff1a;size_t strlen(const char *s); 功能&#xff1a;统计字符串string中字符的个数&#xff0c;字符串的长度在 size_t…

javaone_JavaOne 2014:会议与合同利益冲突

javaone杜克街咖啡馆&#xff0c;工程师可以在街上进行走廊交谈 。 与签约不兼容 我的第11届JavaOne会议&#xff08;2004年至2014年为11 10 1&#xff09;非常出色。 值得参加此活动并结识社区中所有的人。 现在&#xff0c;这里是绅士的&#xff0c;但 。 除了经济上的明显…

什么流读取MultipartFile_深入理解并运用Node中的IO模型流

在 NodeJs 中&#xff0c;流随处可见&#xff0c;读/写文件流&#xff0c;HTTP请求/返回流&#xff0c;stdin/stdout流。理解并运用好流会让你的Node更具力量。Streamlib/_stream_readable.jslib/_stream_writable.jslib/_stream_tranform.jslib/_stream_duplex.js流主要有可读…