HarmonyOS 应用开发之RelationalStore开发

场景介绍

RelationalStore提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。

基本概念

  • 谓词:数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。

  • 结果集:指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便地拿到用户想要的数据。

约束限制

  • 系统默认日志方式是WAL(Write Ahead Log)模式,系统默认落盘方式是FULL模式。

  • 数据库中连接池的最大数量是4个,用以管理用户的读操作。

  • 为保证数据的准确性,数据库同一时间只能支持一个写操作。

  • 当应用被卸载完成后,设备上的相关数据库文件及临时文件会被自动清除。

  • 使用API11新增的端云同步等接口时,需要确保已实现云服务功能。

接口说明

接口名称描述
OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode)获得一个相关的OH_Rdb_Store实例,操作关系型数据库。
OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql)执行包含指定参数但不返回值的SQL语句。
OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket)向目标表中插入一行数据。
OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valuesBucket, OH_Predicates *predicates)根据OH_Predicates的指定实例对象更新数据库中的数据。
OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates)根据OH_Predicates的指定实例对象从数据库中删除数据。
OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length)根据指定条件查询数据库中的数据。
OH_Rdb_DeleteStore(const OH_Rdb_Config *config)删除数据库。
OH_VBucket_PutAsset(OH_VBucket *bucket, const char *field, Rdb_Asset *value)把Rdb_Asset类型的数据放到指定的OH_VBucket对象中。
OH_VBucket_PutAssets(OH_VBucket *bucket, const char *field, Rdb_Asset *value, uint32_t count)把Rdb_Asset数组类型的数据放到指定的OH_VBucket对象中。
OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint32_t count, Rdb_DistributedType type, const Rdb_DistributedConfig *config)设置分布式数据库表。
OH_Rdb_FindModifyTime(OH_Rdb_Store *store, const char *tableName, const char *columnName, OH_VObject *values)获取数据库指定表中指定列的数据的最后修改时间。
OH_Rdb_CloudSync(OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[], uint32_t count, const Rdb_ProgressObserver *observer)手动执行对指定表的端云同步,使用该接口需要实现云服务功能。
int OH_Data_Asset_SetName(Data_Asset *asset, const char *name)为资产类型数据设置名称。
int OH_Data_Asset_SetUri(Data_Asset *asset, const char *uri)为资产类型数据设置绝对路径。
int OH_Data_Asset_SetPath(Data_Asset *asset, const char *path)为资产类型数据设置应用沙箱里的相对路径。
int OH_Data_Asset_SetCreateTime(Data_Asset *asset, int64_t createTime)为资产类型数据设置创建时间。
int OH_Data_Asset_SetModifyTime(Data_Asset *asset, int64_t modifyTime)为资产类型数据设置最后修改时间。
int OH_Data_Asset_SetSize(Data_Asset *asset, size_t size)为资产类型数据设置占用空间大小。
int OH_Data_Asset_SetStatus(Data_Asset *asset, Data_AssetStatus status)为资产类型数据设置状态码。
int OH_Data_Asset_GetName(Data_Asset *asset, char *name, size_t *length)获取资产类型数据的名称。
int OH_Data_Asset_GetUri(Data_Asset *asset, char *uri, size_t *length)获取资产类型数据的绝对路径。
int OH_Data_Asset_GetPath(Data_Asset *asset, char *path, size_t *length)获取资产类型数据在应用沙箱内的相对路径。
int OH_Data_Asset_GetCreateTime(Data_Asset *asset, int64_t *createTime)获取资产类型数据的创建时间。
int OH_Data_Asset_GetModifyTime(Data_Asset *asset, int64_t *modifyTime)获取资产类型数据的最后修改时间。
int OH_Data_Asset_GetSize(Data_Asset *asset, size_t *size)获取资产类型数据的占用空间大小。
int OH_Data_Asset_GetStatus(Data_Asset *asset, Data_AssetStatus *status)获取资产类型数据的状态码。
Data_Asset *OH_Data_Asset_CreateOne()创造一个资产类型实例。使用完毕后需要调用OH_Data_Asset_DestroyOne释放内存。
int OH_Data_Asset_DestroyOne(Data_Asset *asset)销毁一个资产类型实例并回收内存。
Data_Asset **OH_Data_Asset_CreateMultiple(uint32_t count)创造指定数量的资产类型实例。使用完毕后需要调用OH_Data_Asset_DestroyMultiple释放内存。
int OH_Data_Asset_DestroyMultiple(Data_Asset **assets, uint32_t count)销毁指定数量的资产类型实例并回收内存。
int OH_Rdb_Subscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_DataObserver *observer)为数据库注册观察者, 当分布式数据库中的数据发生更改时,将调用回调。
int OH_Rdb_Unsubscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_DataObserver *observer)从数据库中删除指定类型的指定观察者。
int OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *observer)订阅RDB存储的自动同步进程, 当收到自动同步进度的通知时,将调用回调。
int OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *observer)取消订阅RDB存储的自动同步进程。

开发步骤

添加动态链接库

CMakeLists.txt中添加以下lib。

libnative_rdb_ndk.z.so

头文件

#include <database/data/data_asset.h>
#include <database/rdb/oh_cursor.h>
#include <database/rdb/oh_predicates.h>
#include <database/rdb/oh_value_object.h>
#include <database/rdb/oh_values_bucket.h>
#include <database/rdb/relational_store.h>
#include <database/rdb/relational_store_error_code.h>
  1. 获取OH_Rdb_Store实例,创建数据库文件。其中dataBaseDir变量为应用沙箱路径,Stage模式下建议使用数据库目录,参考 Context 的databaseDir属性。FA模式下,由于没有接口获取数据库沙箱路径,可使用应用程序的文件目录,可参考 Context 的getFilesDir接口。area为数据库文件存放的安全区域,详见 contextConstant ,开发时需要实现由AreaMode枚举值对Rdb_SecurityArea枚举值的转换。示例代码如下所示:

    // 创建OH_Rdb_Config对象
    OH_Rdb_Config config;
    // 该路径为应用沙箱路径
    config.dataBaseDir = "xxx";
    // 数据库文件名
    config.storeName = "RdbTest.db";
    // 应用包名
    config.bundleName = "xxx";
    // 应用模块名
    config.moduleName = "xxx";
    // 数据库文件安全等级
    config.securityLevel = OH_Rdb_SecurityLevel::S1;
    // 数据库是否加密
    config.isEncrypt = false;
    // config所占内存大小
    config.selfSize = sizeof(OH_Rdb_Config);
    // 数据库文件存放的安全区域
    config.area = RDB_SECURITY_AREA_EL1;int errCode = 0;
    // 获取获取OH_Rdb_Store实例
    OH_Rdb_Store *store_ = OH_Rdb_GetOrOpen(&config, &errCode);
    
  2. 获取到OH_Rdb_Store后,调用OH_Rdb_Execute接口创建表,并调用OH_Rdb_Insert接口插入数据。示例代码如下所示:

    char createTableSql[] = "CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, ""AGE INTEGER, SALARY REAL, CODES BLOB)";
    // 执行建表语句
    OH_Rdb_Execute(store_, createTableSql);// 创建键值对实例
    OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
    valueBucket->putText(valueBucket, "NAME", "Lisa");
    valueBucket->putInt64(valueBucket, "AGE", 18);
    valueBucket->putReal(valueBucket, "SALARY", 100.5);
    uint8_t arr[] = {1, 2, 3, 4, 5};
    int len = sizeof(arr) / sizeof(arr[0]);
    valueBucket->putBlob(valueBucket, "CODES", arr, len);
    // 插入数据
    int rowId = OH_Rdb_Insert(store_, "EMPLOYEE", valueBucket);
    // 销毁键值对实例
    valueBucket->destroy(valueBucket);
    

说明:
关系型数据库没有显式的flush操作实现持久化,数据插入即保存在持久化文件。

  1. 根据谓词指定的实例对象,对数据进行修改或删除。

    调用OH_Rdb_Update方法修改数据,调用OH_Rdb_Delete方法删除数据。示例代码如下所示:

    // 修改数据
    OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
    valueBucket->putText(valueBucket, "NAME", "Rose");
    valueBucket->putInt64(valueBucket, "AGE", 22);
    valueBucket->putReal(valueBucket, "SALARY", 200.5);
    uint8_t arr[] = {1, 2, 3, 4, 5};
    int len = sizeof(arr) / sizeof(arr[0]);
    valueBucket->putBlob(valueBucket, "CODES", arr, len);OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
    OH_VObject *valueObject = OH_Rdb_CreateValueObject();
    const char *name = "Lisa";
    valueObject->putText(valueObject, name);
    predicates->equalTo(predicates, "NAME", valueObject)->andOperate(predicates);
    uint32_t count = 1;
    double salary = 100.5;
    valueObject->putDouble(valueObject, &salary, count);
    predicates->equalTo(predicates, "SALARY", valueObject);int changeRows = OH_Rdb_Update(store_, valueBucket, predicates);
    valueObject->destroy(valueObject);
    valueBucket->destroy(valueBucket);
    predicates->destroy(predicates);
    
    // 删除数据
    OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
    OH_VObject *valueObject = OH_Rdb_CreateValueObject();
    const char *name = "Lisa";
    valueObject->putText(valueObject, name);
    predicates->equalTo(predicates, "NAME", valueObject);
    int deleteRows = OH_Rdb_Delete(store_, predicates);
    valueObject->destroy(valueObject);
    predicates->destroy(predicates);
    
  2. 根据谓词指定的查询条件查找数据。

    调用OH_Rdb_Query方法查找数据,返回一个OH_Cursor结果集。示例代码如下所示:

    OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");const char *columnNames[] = {"NAME", "AGE"};
    int len = sizeof(columnNames) / sizeof(columnNames[0]);
    OH_Cursor *cursor = OH_Rdb_Query(store_, predicates, columnNames, len);int columnCount = 0;
    cursor->getColumnCount(cursor, &columnCount);// OH_Cursor是一个数据集合的游标,默认指向第-1个记录,有效的数据从0开始
    int64_t age;
    while (cursor->goToNextRow(cursor) == OH_Rdb_ErrCode::RDB_OK) {cursor->getInt64(cursor, 1, &age);
    }// 释放谓词实例
    predicates->destroy(predicates);
    // 释放结果集
    cursor->destroy(cursor);
    
  3. 向数据库表中插入资产类型数据。

    // 列的属性为单个资产类型时,sql语句中应指定为asset,多个资产类型应指定为assets。
    char createAssetTableSql[] = "CREATE TABLE IF NOT EXISTS asset_table (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 asset, data2 assets );";
    errCode = OH_Rdb_Execute(storeTestRdbStore_, createAssetTableSql);
    Data_Asset *asset = OH_Data_Asset_CreateOne();
    OH_Data_Asset_SetName(asset, "name0");
    OH_Data_Asset_SetUri(asset, "uri0");
    OH_Data_Asset_SetPath(asset, "path0");
    OH_Data_Asset_SetCreateTime(asset, 1);
    OH_Data_Asset_SetModifyTime(asset, 1);
    OH_Data_Asset_SetSize(asset, 1);
    OH_Data_Asset_SetStatus(asset, Data_AssetStatus::ASSET_NORMAL);
    errCode = OH_VBucket_PutAsset(valueBucket, "data1", asset);Data_Asset **assets = OH_Data_Asset_CreateMultiple(2);OH_Data_Asset_SetName(assets[0], "name0");
    OH_Data_Asset_SetUri(assets[0], "uri0");
    OH_Data_Asset_SetPath(assets[0], "path0");
    OH_Data_Asset_SetCreateTime(assets[0], 1);
    OH_Data_Asset_SetModifyTime(assets[0], 1);
    OH_Data_Asset_SetSize(assets[0], 1);
    OH_Data_Asset_SetStatus(assets[0], Data_AssetStatus::ASSET_NORMAL);OH_Data_Asset_SetName(assets[1], "name1");
    OH_Data_Asset_SetUri(assets[1], "uri1");
    OH_Data_Asset_SetPath(assets[1], "path1");
    OH_Data_Asset_SetCreateTime(assets[1], 1);
    OH_Data_Asset_SetModifyTime(assets[1], 1);
    OH_Data_Asset_SetSize(assets[1], 1);
    OH_Data_Asset_SetStatus(assets[1], Data_AssetStatus::ASSET_NORMAL);errCode = OH_VBucket_PutAssets(valueBucket, "data2", assets, assetsCount);
    int rowID = OH_Rdb_Insert(cursorTestRdbStore_, table, valueBucket);
    // 释放Data_Asset*和Data_Asset**
    OH_Data_Asset_DestroyMultiple(assets, 2);
    OH_Data_Asset_DestroyOne(asset);
    
  4. 从结果集中读取资产类型数据。

    OH_Predicates *predicates = OH_Rdb_CreatePredicates("asset_table");OH_Cursor *cursor = OH_Rdb_Query(cursorTestRdbStore_, predicates, NULL, 0);
    cursor->goToNextRow(cursor);uint32_t assetCount = 0;
    // assetCount作为出参获取该列资产类型数据的数量
    errCode = cursor->getAssets(cursor, 2, nullptr, &assetCount);
    Data_Asset **assets = OH_Data_Asset_CreateMultiple(assetCount);
    errCode = cursor->getAssets(cursor, 2, assets, &assetCount);
    Data_Asset *asset = assets[1];char name[10] = "";
    size_t nameLength = 10;
    errCode = OH_Data_Asset_GetName(asset, name, &nameLength);char uri[10] = "";
    size_t uriLength = 10;
    errCode = OH_Data_Asset_GetUri(asset, uri, &uriLength);char path[10] = "";
    size_t pathLength = 10;
    errCode = OH_Data_Asset_GetPath(asset, path, &pathLength);int64_t createTime = 0;
    errCode = OH_Data_Asset_GetCreateTime(asset, &createTime);int64_t modifyTime = 0;
    errCode = OH_Data_Asset_GetModifyTime(asset, &modifyTime);size_t size = 0;
    errCode = OH_Data_Asset_GetSize(asset, &size);Data_AssetStatus status = Data_AssetStatus::ASSET_NULL;
    errCode = OH_Data_Asset_GetStatus(asset, &status);predicates->destroy(predicates);
    OH_Data_Asset_DestroyMultiple(assets, assetCount);
    cursor->destroy(cursor);
    
  5. 查询数据的最后修改时间。调用OH_Rdb_FindModifyTime查询指定表中指定列的数据的最后修改时间,该接口返回一个有两列数据的OH_Cursor对象,第一列为传入的主键/RowId,第二列为最后修改时间。示例代码如下所示:

    OH_VObject *values = OH_Rdb_CreateValueObject();
    int64_t keys[] = { 1 };
    values->putInt64(values, keys, 1);
    OH_Cursor *cursor;
    cursor = OH_Rdb_FindModifyTime(storeTestRdbStore_, "EMPLOYEE", "ROWID", values);
    
  6. 创建分布式表。调用OH_Rdb_Execute接口创建表之后,可以将已创建的表设置成分布式表,并配置相关的分布式选项。使用该接口需要实现云服务功能。示例代码如下所示:

    constexpr int TABLE_COUNT = 1;
    const char *table[TABLE_COUNT];
    table[0] = "EMPLOYEE";
    int errcode = OH_Rdb_SetDistributedTables(storeTestRdbStore_, table, TABLE_COUNT, Rdb_DistributedType::DISTRIBUTED_CLOUD, &config);
    
  7. 对分布式表手动执行端云同步。调用OH_Rdb_SetDistributedTables创建分布式表之后,可以对该表进行手动端云同步。使用该接口需要实现云服务功能。示例代码如下所示:

    // 定义回调函数
    void CloudSyncObserverCallback(void *context, Rdb_ProgressDetails *progressDetails)
    {
    // do something
    }
    const Rdb_ProgressObserver observer = { .context = nullptr, .callback = CloudSyncObserverCallback };
    OH_Rdb_CloudSync(storeTestRdbStore_, Rdb_SyncMode::SYNC_MODE_TIME_FIRST, table, TABLE_COUNT, &observer);
    
  8. 将数据观察者注册到指定的存储对象(store)上,并订阅指定类型(type)的事件。在数据发生变化时,系统会调用相应的回调函数来处理进度观察。调用OH_Rdb_Subscribe接口订阅数据变化事件。使用该接口需要实现云服务功能。示例代码如下所示:

    // 定义回调函数
    void RdbSubscribeBriefCallback(void *context, const char *values[], uint32_t count)
    {
    // do something
    }
    Rdb_BriefObserver briefObserver;
    const Rdb_BriefObserver briefObserver = { .context = nullptr, .callback = RdbSubscribeBriefCallback };
    OH_Rdb_Subscribe(storeTestRdbStore_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD, &briefObserver);
    
  9. 从指定的存储对象(store)中取消对指定类型(type)的事件的订阅。取消后,系统将不再调用相应的回调函数来处理进度观察。调用OH_Rdb_Unsubscribe接口取消订阅数据变化事件。使用该接口需要实现云服务功能。示例代码如下所示:

    // 定义回调函数
    void RdbSubscribeBriefCallback(void *context, const char *values[], uint32_t count)
    {
    // do something
    }
    Rdb_BriefObserver briefObserver = RdbSubscribeBriefCallback;
    const Rdb_DataObserver briefObs = { .context = nullptr, .callback.briefObserver = briefObserver };
    OH_Rdb_Unsubscribe(storeTestRdbStore_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD, &briefObs);
    
  10. 将进度观察者注册到指定的存储对象(store)上,以便订阅自动同步进度的事件。当存储对象进行自动同步时,系统会调用相应的回调函数处理进度观察。调用OH_Rdb_SubscribeAutoSyncProgress接口订阅自动同步进度事件。使用该接口需要实现云服务功能。示例代码如下所示:

    // 定义回调函数
    void RdbProgressObserverCallback(void *context, Rdb_ProgressDetails *progressDetails)
    {
    // do something
    }
    const Rdb_ProgressObserver observer = { .context = nullptr, .callback = RdbProgressObserverCallback };
    OH_Rdb_SubscribeAutoSyncProgress(storeTestRdbStore_, &observer);
    
  11. 从指定的存储对象(store)中取消订阅自动同步进度的事件。取消后,系统将不再调用相应的回调函数来处理进度观察。调用OH_Rdb_UnsubscribeAutoSyncProgress接口取消订阅自动同步进度事件。使用该接口需要实现云服务功能。示例代码如下所示:

    // 定义回调函数
    void RdbProgressObserverCallback(void *context, Rdb_ProgressDetails *progressDetails)
    {
    // do something
    }
    const Rdb_ProgressObserver observer = { .context = nullptr, .callback = RdbProgressObserverCallback };
    OH_Rdb_UnsubscribeAutoSyncProgress(storeTestRdbStore_, &observer);
    
  12. 删除数据库。调用OH_Rdb_DeleteStore方法,删除数据库及数据库相关文件。示例代码如下:

    // 释放数据库实例
    OH_Rdb_CloseStore(store_);
    // 删除数据库文件
    OH_Rdb_DeleteStore(&config);
    

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

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

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

相关文章

HTTP响应头和请求头信息对照

HTTP请求头提供了关于请求&#xff0c;响应或者其他的发送实体的信息。HTTP的头信息包括通用头、请求头、响应头和实体头四个部分。每个头域由一个域名&#xff0c;冒号&#xff08;:&#xff09;和域值三部分组成。 通用头标&#xff1a;即可用于请求&#xff0c;也可用于响应…

字典树基础(Java实现)

字典树也叫Trie&#xff0c;是一种树形结构&#xff0c;其中每个节点可以存储一些变量表示该字符串出现的数量。每条边表示一个字符&#xff0c;如节点9存储一个变量cnt&#xff0c;说明存在三个字符串为“cbc” 例题&#xff1a;前缀判定 import java.math.BigInteger; impor…

set/ multiset 容器(二)

一、set查找和统计 函数原型&#xff1a; find(key); //查找key是否存在,若存在&#xff0c;返回该键的元素的迭代器&#xff1b;若不存在&#xff0c;返回 set.end(); count(key); //统计key的元素个数代码示例&#xff1a; #include<iostream> using namespace std;…

【Java入门教程】第十八讲:String类的常见操作及其应用

Java是一种广泛使用的编程语言&#xff0c;它的标准库中包含了大量的类和方法&#xff0c;以支持各种编程任务。在这些类中&#xff0c;String类无疑是最常用、最重要的类之一。 String类在Java中用于表示和操作字符串&#xff0c;即字符序列。本文将详细介绍String类的基本概…

算法刷题记录 Day34

算法刷题记录 Day34 Date: 2024.03.30 lc 63. 不同路径II class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& G) {// dp[i][j]表示从&#xff08;0&#xff0c;0&#xff09;到&#xff08;i,j&#xff09;的路径数&#xff1b;/…

Kubernetes(k8s):网络插件之Calico安装与详解

Kubernetes&#xff08;k8s&#xff09;&#xff1a;网络插件之Calico安装与详解 1、什么是Calico&#xff1f;2、安装和配置Calico&#xff08;控制节点-master执行&#xff09;3、配置网络策略4、 Calico 的 yaml 文件部分详解1、ConfigMap配置2、DaemonSet 配置 5、calico-k…

Vue自定义组件中使用CSS变量设置样式?

在 Vue 自定义组件中使用 CSS 变量来设置样式&#xff0c;你可以通过在组件的样式中使用 var(–variable-name) 来引用 CSS 变量。然后&#xff0c;在组件的根元素或具体的元素上&#xff0c;使用 :style 绑定来动态设置 CSS 变量的值。以下是一个示例代码。 子组件 (CustomCo…

基于mqtt的物联网控制移动应用程序开发

具体实现问题 MQTT模型、特点、服务质量、报文、消息类型表 java实现mqtt两种方式&#xff1a;Paho Java原生库、spring boot MQTT与HTTP&#xff1a;哪一个最适合物联网&#xff1f; mqtt协议和http协议区别 应用是如何实现mqtt协议 通过调用安卓的MQTT库来实现MQTT协议&…

【智能算法】蜜獾算法(HBA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2021年&#xff0c;FA Hashim等人受到自然界中蜜獾狩猎行为启发&#xff0c;提出了蜜獾算法&#xff08;(Honey Badger Algorithm&#xff0c;HBA&#xff09;。 2.算法原理 2.1算法思想 蜜獾以其…

【力扣】80.删除有序数组中的重复项Ⅱ

80.删除有序数组中的重复项Ⅱ 题目描述 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次&#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用…

Mysql 常用SQL语句

1、查看mysql中所有的数据库&#xff0c; show databases; 2、创建库 create database 库名;&#xff08;也可以用 create database if not exists 库名; 表示如果库不存在再创建&#xff09; 例&#xff1a;create database if not exists ecology; 3、删除库 …

负载均衡:实现高效稳定的网络服务

随着互联网技术的快速发展&#xff0c;网络应用服务的规模和复杂性日益增加。为了满足日益增长的用户需求&#xff0c;确保服务的高可用性和稳定性&#xff0c;负载均衡技术应运而生。本文将详细介绍负载均衡的概念、原理、分类以及应用场景&#xff0c;帮助读者深入了解这一关…

[网鼎杯 2020 朱雀组]Nmap1

打开题目 在源代码中看到了提示 先随便输入127.0.0.1 那我们试试输入 127.0.0.1 | ls 可以看到 | 被转义符号\所转义 那我们输入 127.0.0.1 /| ls 得到三条反斜线 我们猜测&#xff0c;我们输入的东西是被escapeshellarg和escapeshellcmd处理过后的结果 我们输入的东西必须…

element-ui tag 组件源码分享

今日简单分享一下 tag 组件的源码实现&#xff0c;主要从以下三个方面来分享&#xff1a; 1、tag 组件页面结构 2、tag 组件属性 3、tag 组件方法 一、tag 组件页面结构 vue2 中使用 jsx 语法小结&#xff1a; 1.1 需要安装 babel-plugin-transform-vue-jsx 和 vue/babel-…

echarts仪表盘特殊样式

const drawChartOption function (value, max) {const colorConfig {name: 测试,colorList: {text: #fff,line2: {type: linear,x: 0, // 右y: 0, // 下x2: 1, // 左y2: 0, // 上colorStops: [// {// offset: 0,// color: transparent// },{offset: 0.1,color: #031e…

Permission Denial: package=android does not belong to uid=2000

02-01 03:14:17.230 1685 2701 W ContextImpl: Calling a method in the system process without a qualified user: xxxxxxxxx 02-01 03:14:17.231 1685 2701 W ActivityTaskManager: Permission Denial: packageandroid does not belong to uid2000 这类问题往往是调用端…

服务器托管让服务器管理更轻松高效

在信息化飞速发展的今天&#xff0c;服务器作为企业数据处理和信息存储的核心设备&#xff0c;其管理的重要性日益凸显。服务器托管&#xff0c;作为一种高效、专业的服务器管理方式&#xff0c;正逐渐成为众多企业的首选。那么&#xff0c;服务器托管究竟是如何让服务器管理更…

AI版青花瓷

3月22日&#xff0c;Suno正式上线V3版本&#xff0c;很多人都称之为AI音乐的"ChatGPT"时刻&#xff0c;从此人人都可以是作曲家&#xff0c;先来听下最近霸榜的只因你太美baby来感受下它的厉害之处&#xff08;我已经被洗脑了哈哈&#xff09; 1. Suno 介绍 根据Sun…

配电线路故障仿真中的基本概念

1. 什么事故障录波&#xff1a; 记录电力系统在发生故障时的电压、电流等关键参数的波形变化。 2. 电压时间型保护装置&#xff1a; 电压时间型保护装置的核心思想是通过设定一定的电压阈值和时间延迟&#xff0c;当检测到的电压超过这个阈值并且持续时间超过设定的时间时&a…

sqlmap基础知识

一、sqlmap简介 sqlmap是一个开源的渗透测试工具&#xff0c;可以自动检测和利用SQL注入漏洞以及接管数据库服务器的过程。 官网&#xff1a; sqlmap.org 核心功能 漏洞检测漏洞利用 学习关键点 基于sqlmap进行sql注入漏洞的检测&#xff0c;注入利用和攻击基于sqlmap进…