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,一经查实,立即删除!

相关文章

字典树基础(Java实现)

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

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…

【智能算法】蜜獾算法(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算法思想 蜜獾以其…

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、删除库 …

[网鼎杯 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…

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

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

AI版青花瓷

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

便携式组件el测试仪讲解

TH-EL3便携式组件EL&#xff08;电致发光&#xff09;测试仪是一种专门用于检测光伏组件质量的设备。该设备基于电致发光的原理&#xff0c;通过非破坏性的方式快速准确地检测出光伏组件内部的各种缺陷和问题。 产品概述 便携式组件EL测试仪是一种轻便、易于携带的设备&#…

Mysql实战--为什么表数据删掉一半,表文件大小不变

经常会有同学来问我&#xff0c;我的数据库占用空间太大&#xff0c;我把一个最大的表删掉了一半的数据&#xff0c;怎么表文件的大小还是没变&#xff1f; 那么今天&#xff0c;我就和你聊聊数据库表的空间回收&#xff0c;看看如何解决这个问题。 这里&#xff0c;我们还是针…

云容器引擎CCE弹性伸缩

CCE弹性伸缩介绍 CCE的弹性伸缩能力分为如下两个维度&#xff1a; 工作负载弹性伸缩&#xff1a;即调度层弹性&#xff0c;主要是负责修改负载的调度容量变化。例如&#xff0c;HPA是典型的调度层弹性组件&#xff0c;通过HPA可以调整应用的副本数&#xff0c;调整的副本数会…

数据结构进阶篇 之 【堆的应用】(堆排序,TOP-K问题)详细讲解

所有人都关心我飞的高不高&#xff0c;只有我妈关心我翅膀硬不硬 一、堆的应用 1. 堆排序 1.1 建堆 1.2 利用堆删除思想来进行排序 2.TOP-K问题 二、完结撒❀ –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–…

如何快速有效地压缩图片大小?这款在线工具可保证图片质量

当你需要上传或发送大量图片时&#xff0c;大体积的图片文件往往会让我们感到困扰&#xff0c;如何快速有效的压缩图片大小成了比较关键的问题&#xff0c;在图片压缩时&#xff0c;我们还需要担心的就是会不会对图片质量有损害&#xff0c;想要做到图片无损压缩就需要用到一些…

go和Java该如何选择?

今天&#xff0c;每个企业都需要一个软件应用程序&#xff0c;从初创公司到大型公司如果你想以最有效的方式运行业务&#xff0c;你必须把它列在网上。竞争并没有就此结束 但重要的是您能够以多简单、多快速的方式创建软件应用程序-这是引领竞争的正确方式。 选择最适合您的软…

MegaSeg Pro for Mac v6.3.1 注册激活版 音视频DJ混音工具

MegaSeg Pro for Mac是一款专业的DJ和广播自动化软件&#xff0c;旨在为音乐专业人士提供强大的音乐播放和演播功能。这款软件具有多种功能&#xff0c;包括强大的音乐库管理&#xff0c;支持导入和组织大量音乐文件&#xff0c;可以轻松管理你的音乐收藏。它支持广泛的音频格式…

WPF学习笔记-FlowDocument流文档基础知识和基本操作

文章目录 概述一、块元素和内联元素1.1 块元素&#xff08;Block类&#xff09;1.2 内联元素&#xff08;Inline类&#xff09;二、Paragraph元素2.1 基本属性设置2.2 将内联元素Inline添加到Inlines中2.3 设置中西文字体不一样 三、Table元素3.1 添加新的Table3.2 添加列3.3 添…

深度学习系列-python实现-初步学习构建神经网络

深度学习系列-python实现-初步学习构建神经网络 前言1.在Keras中加载MNIST数据集2.构建简单的神经网络模型3.训练模型4.模型的预测和评估5.总结 前言 在数字时代&#xff0c;数据已经成为了一种无处不在的资源。从商业分析到科学研究&#xff0c;从人工智能到机器学习&#xf…

固态硬盘一年不通电数据就没了吗?丢失了怎么办

随着数字化时代的到来&#xff0c;数据的安全性和持久性变得尤为重要。作为现代电子设备中常见的存储设备&#xff0c;固态硬盘&#xff08;SSD&#xff09;以其高效、快速的特点受到广大用户的青睐。然而&#xff0c;有关固态硬盘长时间不通电后数据会丢失的担忧也时常困扰着用…

报错:AttributeError: module ‘numpy‘ has no attribute ‘unit8‘解决

错误问题&#xff1a; 解决方法&#xff1a; 哥们姐们仔细一点吧这个unit8是打错了&#xff0c;无非就是uint8写成了unit8 应该是【uint8】&#xff0c;以后敲代码仔细点哦