HarmonyOS:通过键值型数据库实现数据持久化

一、场景介绍

键值型数据库存储键值对形式的数据,当需要存储的数据没有复杂的关系模型,比如存储商品名称及对应价格、员工工号及今日是否已出勤等,由于数据复杂度低,更容易兼容不同数据库版本和设备类型,因此推荐使用键值型数据库持久化此类数据。

二、约束限制

  • 设备协同数据库,针对每条记录,Key的长度≤896 Byte,Value的长度<4 MB。
  • 单版本数据库,针对每条记录,Key的长度≤1 KB,Value的长度<4 MB。
  • 每个应用程序最多支持同时打开16个键值型分布式数据库。
  • 键值型数据库事件回调方法中不允许进行阻塞操作,例如修改UI组件。

三、接口说明

以下是键值型数据库持久化功能的相关接口,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下表均以callback形式为例,更多接口及使用方式请见分布式键值数据库

接口名称 描述
createKVManager(config: KVManagerConfig): KVManager 创建一个KVManager对象实例,用于管理数据库对象。
getKVStore(storeId: string, options: Options, callback: AsyncCallback): void 指定options和storeId,创建并得到指定类型的KVStore数据库。
put(key: string, value: Uint8Array | string | number | boolean, callback: AsyncCallback): void 添加指定类型的键值对到数据库。
get(key: string, callback: AsyncCallback<boolean | string | number | Uint8Array>): void 获取指定键的值。
delete(key: string, callback: AsyncCallback): void 从数据库中删除指定键值的数据。
closeKVStore(appId: string, storeId: string, callback: AsyncCallback): void 通过storeId的值关闭指定的分布式键值数据库。
deleteKVStore(appId: string, storeId: string, callback: AsyncCallback): void 通过storeId的值删除指定的分布式键值数据库。

四、开发步骤

若要使用键值型数据库,首先要获取一个KVManager实例,用于管理数据库对象。示例代码如下所示:

4.1 Stage模型示例效果图

1. 创建KVManager实例


2. 初始化 KVStore


3. 调用put()方法向键值数据库中插入数据


4. 调用get()方法获取指定键的值


5. 调用delete()方法删除指定键值的数据


6. 通过storeId的值关闭指定的分布式键值数据库


7. 创建KVManager实例

4.2 Stage模型示例代码
复制代码
// 导入模块
import { distributedKVStore } from '@kit.ArkData';

// Stage模型
import { window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';


let kvManager: distributedKVStore.KVManager | undefined = undefined;
let context = getContext(this) as common.UIAbilityContext;
let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;

const KEY_TEST_STRING_ELEMENT = 'key_test_string';
const VALUE_TEST_STRING_ELEMENT = 'value_test_string';

const STORE_ID = 'testStore01';
const APP_ID = 'com.example.learnharmonyos';

function initKVManager() {
  const kvManagerConfig: distributedKVStore.KVManagerConfig = {
    context: context,
    bundleName: 'com.example.learnharmonyos'
  };
  try {
    // 创建KVManager实例
    kvManager = distributedKVStore.createKVManager(kvManagerConfig);
    console.info('初始化 Succeeded in creating KVManager.');
    // 继续创建获取数据库
  } catch (e) {
    let error = e as BusinessError;
    console.error(`初始化 Failed to create KVManager. Code:${error.code},message:${error.message}`);
  }
}


/**
 * 初始化 KVStore
 */
function initKVStore() {
  // 1. 若要使用键值型数据库,首先要获取一个KVManager实例,用于管理数据库对象
  if (kvManager == undefined) {
    console.error("kvManager == undefined 不能继续执行下面操作")
    return
  }
  kvManager = kvManager as distributedKVStore.KVManager;

  //2. 创建并获取键值数据库。
  try {
    const options: distributedKVStore.Options = {
      createIfMissing: true,
      encrypt: false,
      backup: false,
      autoSync: false,
      // kvStoreType不填时,默认创建多设备协同数据库
      kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
      // 多设备协同数据库:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION,
      securityLevel: distributedKVStore.SecurityLevel.S3
    };
    kvManager.getKVStore<distributedKVStore.SingleKVStore>(STORE_ID, options,
      (err, store: distributedKVStore.SingleKVStore) => {
        if (err) {
          console.error(`执行 getKVStore Failed to get KVStore: Code:${err.code},message:${err.message}`);
          return;
        }
        console.info('执行 getKVStore Succeeded in getting KVStore.');
        kvStore = store;
        // 请确保获取到键值数据库实例后,再进行相关数据操作
        if (kvStore == undefined) {
          console.error("kvStore == undefined 不能继续执行下面操作")
          return
        }
        kvStore = kvStore as distributedKVStore.SingleKVStore;
      });
  } catch (e) {
    let error = e as BusinessError;
    console.error(`执行 getKVStore An unexpected error occurred. Code:${error.code},message:${error.message}`);
  }
}

/**
 * 3. 调用put()方法向键值数据库中插入数据
 */
function insertData() {
  if (kvStore == undefined) {
    console.error("插入数据 kvStore == undefined 不能继续执行下面操作")
    return
  }
  try {
    kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {
      if (err !== undefined) {
        console.error(`插入数据 Failed to put data. Code:${err.code},message:${err.message}`);
        return;
      }
      console.info('插入数据 Succeeded in putting data.');
    });
  } catch (e) {
    let error = e as BusinessError;
    console.error(`插入数据 An unexpected error occurred. Code:${error.code},message:${error.message}`);
  }
}

/**
 * 4. 调用get()方法获取指定键的值
 */
function getData() {
  if (kvStore == undefined) {
    console.error("插入数据 kvStore == undefined 不能继续执行下面操作")
    return
  }
  try {
    kvStore.get(KEY_TEST_STRING_ELEMENT, (err, data) => {
      if (err != undefined) {
        console.error(`获取数据 Failed to get data. Code:${err.code},message:${err.message}`);
        return;
      }
      console.info(`获取数据 Succeeded in getting data. Data:${data}`);
    });
  } catch (e) {
    let error = e as BusinessError;
    console.error(`获取数据 Failed to get data. Code:${error.code},message:${error.message}`);
  }
}

/**
 * 5. 调用delete()方法删除指定键值的数据
 */

function testdelete() {
  if (kvStore == undefined) {
    console.error("调用delete()方法 kvStore == undefined 不能继续执行下面操作")
    return
  }
  try {
    kvStore.delete(KEY_TEST_STRING_ELEMENT, (err) => {
      if (err !== undefined) {
        console.error(`调用delete()方法 Failed to delete data. Code:${err.code},message:${err.message}`);
        return;
      }
      console.info('调用delete()方法 Succeeded in deleting data.');
    });
  } catch (e) {
    let error = e as BusinessError;
    console.error(`调用delete()方法 An unexpected error occurred. Code:${error.code},message:${error.message}`);
  }
}

/**
 * 6. 通过storeId的值关闭指定的分布式键值数据库
 */
function testSetStoreId() {
  if (kvManager == undefined) {
    console.error("调用 testSetStoreId()方法 kvManager == undefined 不能继续执行下面操作")
    return
  }
  try {
    kvStore = undefined;
    kvManager.closeKVStore(APP_ID, STORE_ID, (err: BusinessError) => {
      if (err) {
        console.error(`调用 testSetStoreId()方法 Failed to close KVStore.code is ${err.code},message is ${err.message}`);
        return;
      }
      console.info('调用 testSetStoreId()方法 Succeeded in closing KVStore');
    });
  } catch (e) {
    let error = e as BusinessError;
    console.error(`调用 testSetStoreId()方法 An unexpected error occurred. Code:${error.code},message:${error.message}`);
  }
}

/**
 * 7. 通过storeId的值删除指定的分布式键值数据库
 */
function testSetStoreId2() {
  if (kvManager == undefined) {
    console.error("调用 testSetStoreId2()方法 kvManager == undefined 不能继续执行下面操作")
    return
  }
  try {
    kvStore = undefined;
    kvManager.deleteKVStore(APP_ID, STORE_ID, (err: BusinessError) => {
      if (err) {
        console.error(`调用 testSetStoreId2()方法 Failed to close KVStore.code is ${err.code},message is ${err.message}`);
        return;
      }
      console.info('调用 testSetStoreId2()方法 Succeeded in closing KVStore');
    });
  } catch (e) {
    let error = e as BusinessError;
    console.error(`调用 testSetStoreId2()方法 An unexpected error occurred. Code:${error.code},message:${error.message}`);
  }
}

@Entry
@Component
struct TestDistributedKVStore {
  @State message: string = '通过键值型数据库实现数据持久化';

  build() {
    Column({ space: 10 }) {
      Text(this.message)
        .id('TestDistributedKVStoreHelloWorld')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Button("初始化 KVManager")
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .onClick(() => {
          initKVManager();
        })
      Button("初始化 initKVStore")
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .onClick(() => {
          initKVStore();
        })
      Button("插入数据")
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .onClick(() => {
          insertData();
        })
      Button("获取数据")
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .onClick(() => {
          getData();
        })
      Button("删除")
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .onClick(() => {
          testdelete();
        })
      Button("通过storeId的值关闭指定的分布式键值数据库")
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .onClick(() => {
          testSetStoreId();
        })
      Button("通过storeId的值删除指定的分布式键值数据库")
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .onClick(() => {
          testSetStoreId2();
        })
    }
    .padding({ top: 30 })
    .height('100%')
    .width('100%')
  }
}
相关推荐
二流小码农19 分钟前
鸿蒙开发:了解Canvas绘制
android·ios·harmonyos
祖师爷科技1 小时前
鸿蒙项目源码-记账本app个人财物管理-原创!原创!原创!
华为·harmonyos
_唐浮5 小时前
【HarmonyOS Next】Promise你可能理解错了
harmonyos·arkts
妮妮分享6 小时前
维智 Harmony NEXT 定位 SDK:鸿蒙生态下的空间智能应用实践
人工智能·华为·ai编程·harmonyos
二流小码农6 小时前
鸿蒙开发:动态添加节点
android·ios·harmonyos
小藤神7 小时前
鸿蒙ArkTS 一次开发 多端部署 三层架构 LazyForEach懒加载 Account Kit华为一键登录
前端·harmonyos·arkts
别说我什么都不会7 小时前
OpenHarmony解读之设备认证:pake协议-服务端响应pake start请求(2)
物联网·嵌入式·harmonyos
马剑威(威哥爱编程)7 小时前
谷歌Android闭源与鸿蒙崛起:一场关于技术主权的生态博弈
android·华为·harmonyos
一只小风华~8 小时前
鸿蒙harmonyOS:笔记 正则表达式
前端·笔记·华为·正则表达式·harmonyos