ESP-C3入门8. 连接WiFi并打印信息
ESP-C3入门8. 连接WiFi并打印信息
- 一、ESP32 连接WiFi的基本操作流程
- 1. 初始化nvs存储
- 2. 配置WiFi工作模式
- 3. 设置WiFi登陆信息
- 4. 启动WiFi
- 5. 开启连接
- 6. 判断是否成功
- 二、事件处理函数
- 1. 定义事件处理函数
- 2. 创建事件组
- 3. 在事件处理函数中设置事件组位
- 4. 在其他任务中等待事件组位
- 5. 注册事件处理函数
- 6. 如果有必要取消注册
- 三、事件组的使用
- 1. 创建事件组
- 2. 向事件组中设置事件
- 3. 在其它任务中等待事件
- 四、实现过程
- 1. WiFi初始化函数做以下事情
- 2. WiFi Station模式初始化
- 3. 事件回调
- 五、完整代码
本文示例代码主要来自官方开源仓库:
https://gitee.com/EspressifSystems/book-esp32c3-iot-projects
一、ESP32 连接WiFi的基本操作流程
1. 初始化nvs存储
nvs_flash_init();
tcpip_adapter_init();
2. 配置WiFi工作模式
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_init_config);
esp_wifi_set_storage(WIFI_STORAGE_RAM);
esp_wifi_set_mode(WIFI_MODE_STA);
3. 设置WiFi登陆信息
wifi_config_t wifi_config = {.sta = {.ssid = "your_SSID",.password = "your_password",},
};
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
4. 启动WiFi
esp_wifi_start();
5. 开启连接
esp_wifi_connect();
6. 判断是否成功
wifi_ap_record_t ap_info;
esp_wifi_sta_get_ap_info(&ap_info);
if (ap_info.authmode != WIFI_AUTH_OPEN) {// 连接成功
} else {// 连接失败
}
二、事件处理函数
在 ESP-IDF 中,一些关键的系统任务(比如,Wi-Fi连接、网络传输等)通常都是在事件驱动的模式下实现的,
系统会生成一些事件,然后由事件处理机制来进行处理。事件处理机制是用于接收并处理系统事件的主要机制,通过它,可以实现自定义的动作(比如,记录日志、进行状态更新等)。
在ESP-IDF中使用事件处理函数有以下步骤:
1. 定义事件处理函数
定义一个函数,用于处理特定的事件,如:
void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{// your code here
}
2. 创建事件组
使用 xEventGroupCreate 函数创建事件组。
3. 在事件处理函数中设置事件组位
在事件处理函数内部,使用 xEventGroupSetBits 函数设置事件组位,以标识事件已经发生。
4. 在其他任务中等待事件组位
使用 xEventGroupWaitBits 函数在其他任务中等待事件组位,以确认事件已经发生。
5. 注册事件处理函数
使用函数(如 esp_event_loop_init)注册事件处理函数,使其生效。
esp_event_handler_register(event_base, event_id, event_handler, arg);
其中:
- event_base 是事件的基础,通常是一个枚举,它表示事件类别,比如 WIFI_EVENT。
- event_id 是事件的 ID,通常也是一个枚举,它表示事件类型,比如 WIFI_EVENT_STA_DISCONNECTED。
- event_handler 是事件处理函数,用来处理事件,从中读取事件数据。
- arg 是一个用户指定的参数,在事件处理函数中可以读取。
6. 如果有必要取消注册
esp_event_handler_unregister(event_base, event_id, event_handler);
三、事件组的使用
ESP-IDF中的事件组是一种线程间同步机制,允许多个任务同时等待特定的事件发生。
在ESP-IDF中使用事件组的步骤是:
1. 创建事件组
EventGroupHandle_t s_event_group = xEventGroupCreate();
2. 向事件组中设置事件
xEventGroupSetBits(s_event_group, BIT0);
3. 在其它任务中等待事件
EventBits_t bits = xEventGroupWaitBits(s_event_group, BIT0, pdFALSE, pdFALSE, portMAX_DELAY);
四、实现过程
1. WiFi初始化函数做以下事情
- 创建一个事件组,用来管理Wi-Fi连接事件。
- 实始化协议栈
- 创建默认事件循环
- WiFi设置为sta模式
- 注册事件处理器
static void wifi_initialize(void)
{// 创建一个事件组,用于管理Wi-Fi连接事件。s_wifi_event_group = xEventGroupCreate();// 初始化 TCP/IP 协议栈。ESP_ERROR_CHECK(esp_netif_init());// 创建默认事件循环。ESP_ERROR_CHECK(esp_event_loop_create_default());// 创建默认的Wi-Fi网络接口。esp_netif_create_default_wifi_sta();// 设置 Wi-Fi 初始化配置为默认配置wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));// 注册事件处理器,以处理 Wi-Fi 和 IP 相关事件ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
}
其中事件组的定义是:
static EventGroupHandle_t s_wifi_event_group = NULL;
2. WiFi Station模式初始化
- 配置WiFi信息
- WiFi工作模式设置为STA
- 启动WiFi
- 等待事件
static void wifi_station_initialize(void)
{// 配置WiFi的配置信息wifi_config_t wifi_config = {.sta = {.ssid = LIGHT_ESP_WIFI_SSID,.password = LIGHT_ESP_WIFI_PASS,// 启用WPA2模式,常用的WiFi连接方式.threshold.authmode = WIFI_AUTH_WPA2_PSK,.pmf_cfg = {.capable = true,.required = false},},};// WiFi工作模式设置为STAESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));// 设置WiFi工作模式ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));// 启动WiFiESP_ERROR_CHECK(esp_wifi_start());ESP_LOGI(TAG, "wifi_station_initialize finished.");// 下面的代码不是必须的,但它演示了程序如何阻塞并等待连接成功/* 等待连接建立(WIFI_CONNECTED_BIT)或连接失败的次数达到最大值(WIFI_FAIL_BIT)。* 这些位通过 event_handler() 设置(详见上面)*/EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);/* xEventGroupWaitBits() 返回调用前的 bits,因此我们可以测试实际发生了什么事件。 */if (bits & WIFI_CONNECTED_BIT) {ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS);} else if (bits & WIFI_FAIL_BIT) {ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS);} else {ESP_LOGE(TAG, "UNEXPECTED EVENT");}
}
xEventGroupWaitBits 函数在这里不是必须的。 它是一个阻塞函数,将等待一个或多个事件位被设置,直到返回时间结束。
本示例中,它等待 WIFI_CONNECTED_BIT 或 WIFI_FAIL_BIT 中的任何一个事件位被设置,并且等待的最长时间是 portMAX_DELAY。
相关参数:
- s_wifi_event_group 是事件组变量,用于存储事件位。
- WIFI_CONNECTED_BIT | WIFI_FAIL_BIT 是要等待的事件位。WIFI_CONNECTED_BIT 表示 Wi-Fi 连接成功的事件,WIFI_FAIL_BIT 表示 Wi-Fi 连接失败的事件。
- pdFALSE 和 pdTRUE 是宏,分别表示布尔值的 false 和 true,此处代表不需要等待所有事件位(pdFALSE)和不清除事件位(pdFALSE)。
- portMAX_DELAY 是一个常量,表示无限等待。
- 返回值(EventBits_t bits)是一个事件位变量,表示返回的事件位。
该代码实现了在等待 Wi-Fi 连接结果的同时不占用 CPU 资源,并在连接成功或失败时记录事件位以作后续处理。
事件组允许每个事件有多个位,前面要定义:
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
这里的BIT0 BIT1由开发者自行定义。
3. 事件回调
// 事件回调
static void event_handler(void *arg, esp_event_base_t event_base,int32_t event_id, void *event_data)
{// 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_STARTif (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {esp_wifi_connect();} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {// 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_DISCONNECTED/* 如果重试次数小于最大重试次数 */if (s_retry_num < LIGHT_ESP_MAXIMUM_RETRY) {esp_wifi_connect();s_retry_num++;ESP_LOGI(TAG, "retry to connect to the AP");} else {xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);}ESP_LOGI(TAG, "connect to the AP fail");} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {// 如果是IP事件,并且事件ID是IP事件STA_GOT_IP// 获取事件结果ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));// 将重试次数重置为 0;s_retry_num = 0;// 通过调用 xEventGroupSetBits 函数,将 WIFI_CONNECTED_BIT 设置到事件组中,表示成功连接到 APxEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);}
}
五、完整代码
#include <string.h>#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"#define LIGHT_ESP_WIFI_SSID "你的WIFI账号"
#define LIGHT_ESP_WIFI_PASS "你的WiFi密码"
#define LIGHT_ESP_MAXIMUM_RETRY 5// 事件组允许每个事件有多个位,这里只使用两个事件:
// 已经连接到AP并获得了IP
// 在最大重试次数后仍未连接
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1static const char *TAG = "wifi connection";// FreeRTOS事件组,连接成功时发出信号
static EventGroupHandle_t s_wifi_event_group = NULL;
static int s_retry_num = 0;// 事件回调
static void event_handler(void *arg, esp_event_base_t event_base,int32_t event_id, void *event_data)
{// 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_STARTif (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {esp_wifi_connect();} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {// 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_DISCONNECTED/* 如果重试次数小于最大重试次数 */if (s_retry_num < LIGHT_ESP_MAXIMUM_RETRY) {esp_wifi_connect();s_retry_num++;ESP_LOGI(TAG, "retry to connect to the AP");} else {xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);}ESP_LOGI(TAG, "connect to the AP fail");} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {// 如果是IP事件,并且事件ID是IP事件STA_GOT_IP// 获取事件结果ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));// 将重试次数重置为 0;s_retry_num = 0;// 通过调用 xEventGroupSetBits 函数,将 WIFI_CONNECTED_BIT 设置到事件组中,表示成功连接到 APxEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);}
}static void wifi_initialize(void)
{// 创建一个事件组,用于管理Wi-Fi连接事件。s_wifi_event_group = xEventGroupCreate();// 初始化 TCP/IP 协议栈。ESP_ERROR_CHECK(esp_netif_init());// 创建默认事件循环。ESP_ERROR_CHECK(esp_event_loop_create_default());// 创建默认的Wi-Fi网络接口。esp_netif_create_default_wifi_sta();// 设置 Wi-Fi 初始化配置为默认配置wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));// 注册事件处理器,以处理 Wi-Fi 和 IP 相关事件ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
}static void wifi_station_initialize(void)
{// 配置WiFi的配置信息wifi_config_t wifi_config = {.sta = {.ssid = LIGHT_ESP_WIFI_SSID,.password = LIGHT_ESP_WIFI_PASS,// 启用WPA2模式,常用的WiFi连接方式.threshold.authmode = WIFI_AUTH_WPA2_PSK,.pmf_cfg = {.capable = true,.required = false},},};// WiFi工作模式设置为STAESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));// 设置WiFi工作模式ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));// 启动WiFiESP_ERROR_CHECK(esp_wifi_start());ESP_LOGI(TAG, "wifi_station_initialize finished.");/* 等待连接建立(WIFI_CONNECTED_BIT)或连接失败的次数达到最大值(WIFI_FAIL_BIT)。* 这些位通过 event_handler() 设置(详见上面)*/EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);/* xEventGroupWaitBits() 返回调用前的 bits,因此我们可以测试实际发生了什么事件。 */if (bits & WIFI_CONNECTED_BIT) {ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS);} else if (bits & WIFI_FAIL_BIT) {ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS);} else {ESP_LOGE(TAG, "UNEXPECTED EVENT");}
}void app_main()
{int i = 0;ESP_LOGE(TAG, "app_main");// 初始化NVS存储区ESP_ERROR_CHECK(nvs_flash_init());// Wi-Fi初始化ESP_LOGI(TAG, "Wi-Fi initialization");wifi_initialize();// Wi-Fi Station初始化wifi_station_initialize();while (1) {ESP_LOGI(TAG, "[%02d] Hello world!", i++);vTaskDelay(pdMS_TO_TICKS(5000));}
}
运行结果:
相关文章:

ESP-C3入门8. 连接WiFi并打印信息
ESP-C3入门8. 连接WiFi并打印信息一、ESP32 连接WiFi的基本操作流程1. 初始化nvs存储2. 配置WiFi工作模式3. 设置WiFi登陆信息4. 启动WiFi5. 开启连接6. 判断是否成功二、事件处理函数1. 定义事件处理函数2. 创建事件组3. 在事件处理函数中设置事件组位4. 在其他任务中等待事件…...

使用python将EXCEL表格中数据转存到数据库
使用Python将excel表格中数据转存到数据库 1. 思路: 1) 使用python读取excel表格中数据 2)根据数据生成sql语句 3)批量运行sql语句 2. 代码: import pandas as pddef readExcel(path, excel_file):return pd.read_e…...

【C++】类和对象(三)
目录 一、构造函数补充 1、初始化列表 1.1、初始化列表概念 1.2、初始化列表性质 2、explicit关键字 二、static成员 1、概念及使用 2、性质总结 三、友元 1、友元函数 2、友元类 四、内部类 五、拷贝对象时的一些编译器优化 一、构造函数补充 在《类和对象&#x…...

vTESTstudio - VT System CAPL Functions - General/Trigger Function
前面文章中我们已经介绍了常用的几种板卡的基本信息,那这些板卡该如何去通过软件调用呢?带着这个问题我们开始新的一块内容 - VT系统相关的自动化控制函数介绍,我会按照不同的板卡来分类,对其可控制的函数进行介绍,方便…...
IDEA 快捷键
ctrlD :复制当前行到下一行 ctrlO : 重写当前类的方法 ctrlshiftu : 大小写转化 Alt 上/下 :跳到上一个、下一个函数 Alt 左/右 : 回到上一个、下一个文件 Alt 回车 : 代码修正 Alt Insert : 插入代码 Ctrl Alt L …...
2023新华为OD机试题 - 入栈出栈(JavaScript) | 刷完必过
入栈出栈 题目 向一个空栈中依次存入正整数 假设入栈元素N(1 <= N <= 2^31-1) 按顺序依次为Nx ... N4、N3、N2、N1, 当元素入栈时,如果N1=N2+...Ny (y的范围[2,x],1 <= x <= 1000) 则N1到Ny全部元素出栈,重新入栈新元素M(M=2*N1) 如依次向栈存储6、1、2、3,当存…...

微信公众号扫码授权登录思路
引言 上学期研究了一下微信登录相关内容,也写了两三篇笔记,但是最后实际登录流程没有写,主要因为感觉功能完成有所欠缺,一直也没有好的思路;这两天我又看了看官方文档,重新构思了一下微信公众号登录相关的…...
数据结构与算法基础-学习-10-线性表之顺序栈的清理、销毁、压栈、弹栈
一、函数实现顺序栈的其他函数实现,请看之前的博客链接《数据结构与算法基础-学习-09-线性表之栈的理解、初始化顺序栈、判断顺序栈空、获取顺序栈长度的实现》。1、ClearSqStack(1)用途清理栈的空间。只需要栈顶指针和栈底指针相等ÿ…...

Hazel游戏引擎(005)
本人菜鸟,文中若有代码、术语等错误,欢迎指正 我写的项目地址:https://github.com/liujianjie/GameEngineLightWeight(中文的注释适合中国人的你) 文章目录前言关键操作代码文件关键代码代码流程代码文件关键代码exter…...

牛客网Python篇数据分析习题(四)
1.现有一个Nowcoder.csv文件,它记录了牛客网的部分用户数据,包含如下字段(字段与字段之间以逗号间隔): Nowcoder_ID:用户ID Level:等级 Achievement_value:成就值 Num_of_exercise&a…...
盲盒如何创业?
所谓的“盲盒”,受众群体大部分是那些爱碰运气的人,顾客买的是那种在打开盲盒时一刹那的惊喜感和神秘感,在打开盲盒之前,谁也不知道自己会得到什么,这也是为什么消费者更愿意购买的原因。网上的盲盒,主要是…...
第1集丨Java中面向对象相关概念汇总
目录一、基本概念1.1 类1.2 属性1.3 方法1.4 静态1.5 包1.6 import二、高级概念2.1 构造方法2.2 继承2.3 super & this2.4 多态2.5 方法重载2.6 方法重写2.7 访问权限2.8 内部类2.9 final2.10 抽象2.11 接口2.12 匿名类面向对象的编程思想力图使计算机语言中对事物的描述与…...

高性能(二)
三、读写分离和分库分表 1.读写分离 1.1 概述 将数据库的读写操作分散到不同的数据库节点上 通常一主多从一台主数据库负责写,多台从数据库负责读。 主库和从库之间会进行数据同步,以保证从库中数据的准确性。 1.2 问题及解决 1.2.1 问题 主从同…...

Allegro如何实现同一个屏幕界面分屏显示操作指导
Allegro如何实现同一个屏幕界面分屏显示操作指导 在做PCB设计的时候,会需要分屏显示,比如一边是放大的视图,另外一边是缩小的视图,Allegro支持同一个屏幕界面下进行分屏显示,如下图 而且会实时同步起来 如何分屏,具体操作如下 点击View...

前后端一些下载与配置(第二篇 第10天过后)nuxt banner redis 短信服务
NUXT 应该是不用怎么装? 有现成的 axios 还需要在npm吗 好像已经有现成的了 banner banner 笔记汇总P396 Redis Linux安装redis tar -xzvf redis-6.2.6.tar.gz cd redis-6.2.6 照着他做 然后 cd /usr/local/redis/bin ./redis-server /usr/local/redis…...
OSG三维渲染引擎编程学习之四十八:“第五章:OSG场景渲染” 之 “5.6 多重纹理映射”
目录 第五章 OSG场景渲染 5.6 多重纹理映射 5.6.1 多重纹理映射介绍 5.6.2 多重纹理映射示例...

对Node.js 的理解?优缺点?应用场景?
一、是什么 Node.js 是一个开源与跨平台的 JavaScript 运行时环境 在浏览器外运行 V8 JavaScript 引擎(Google Chrome 的内核),利用事件驱动、非阻塞和异步输入输出模型等技术提高性能 可以理解为 Node.js 就是一个服务器端的、非阻塞式I/…...
Bean的生命周期
所谓的生命周期指的是一个对象从诞生到销毁的整个生命过程,我们把这个过程就叫做一个对象的生命周期~~ Bean的生命周期分为以下五大部分: 实例化(为 Bean 分配内存空间) 设置属性(Bean对象注入/装配) 初…...
Python学习-----函数2.0(函数对象,名称空间,作用域-->全局变量与局部变量)
目录 前言: 1.函数对象 (1)函数对象的引用 (2)函数可以放到序列里面 (3)函数可以作为参数 , 传递给另一个函数 2.名称空间 3.作用域 (1)作用域的理解 …...
Java中Json字符串和Java对象的互转
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。诞生于 2002 年。易于人阅读和编写。同时也易于机器解析和生成。JSON 是目前主流的前后端数据传输方式。 JSON 采用完全独立于语言的文本格式,但是也使用了类似于 C 语言家族的…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...

break 语句和 continue 语句
break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行 break break语句用于跳出代码块或循环 1 2 3 4 5 6 for (var i 0; i < 5; i) { if (i 3){ break; } console.log(i); } continue continue语句用于立即终…...