写点什么

鸿蒙 NEXT 开发 - 应用数据持久化之键值型数据库

作者:东林知识库
  • 2025-03-31
    江苏
  • 本文字数:3617 字

    阅读完需:约 12 分钟

1. 应用数据持久化

应用数据持久化,是指应用将内存中的数据通过文件或数据库的形式保存到设备上。内存中的数据形态通常是任意的数据结构或数据对象,存储介质上的数据形态可能是文本、数据库、二进制文件等。


HarmonyOS 标准系统支持典型的存储数据形态,包括用户首选项、键值型数据库、关系型数据库。


  • 用户首选项(Preferences):通常用于保存应用的配置信息。数据通过文本的形式保存在设备中,应用使用过程中会将文本中的数据全量加载到内存中,所以访问速度快、效率高,但不适合需要存储大量数据的场景。

  • 键值型数据库(KV-Store):一种非关系型数据库,其数据以“键值”对的形式进行组织、索引和存储,其中“键”作为唯一标识符。适合很少数据关系和业务关系的业务数据存储,同时因其在分布式场景中降低了解决数据库版本兼容问题的复杂度,和数据同步过程中冲突解决的复杂度而被广泛使用。相比于关系型数据库,更容易做到跨设备跨版本兼容。

  • 关系型数据库(RelationalStore):一种关系型数据库,以行和列的形式存储数据,广泛用于应用中的关系型数据的处理,包括一系列的增、删、改、查等接口,开发者也可以运行自己定义的 SQL 语句来满足复杂业务场景的需要。

2. 应用数据持久化-键值型数据库

2.1 概述

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

2.2 约束限制

  • 设备协同数据库,针对每条记录,Key 的长度≤896 Byte,Value 的长度<4 MB。

  • 单版本数据库,针对每条记录,Key 的长度≤1 KB,Value 的长度<4 MB。

  • 每个应用程序最多支持同时打开 16 个键值型分布式数据库。

  • 键值型数据库事件回调方法中不允许进行阻塞操作,例如修改 UI 组件。

2.3 常用方法

2.3.1 在生命周期函数中添加代码


编辑


import KVStoreUtil from '../utils/KVStoreUtil';
复制代码


  onWindowStageCreate(windowStage: window.WindowStage): void {    // 创建键值型数据库的实例    let context = this.context;    const kvManagerConfig: distributedKVStore.KVManagerConfig = {      context: context,      bundleName: 'com.xt.myApplication'    };    try {      // 创建KVManager实例      let kvManager: distributedKVStore.KVManager | undefined = distributedKVStore.createKVManager(kvManagerConfig);      console.info('Succeeded in creating KVManager.');      // 创建数据库      let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;      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.S1        };        kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', options,          (err, store: distributedKVStore.SingleKVStore) => {            if (err) {              console.error(`Failed to get KVStore: Code:${err.code},message:${err.message}`);              return;            }            console.info('Succeeded in getting KVStore.');            kvStore = store;            // 保存数据库            KVStoreUtil.setKVStore(kvStore)          });      } catch (e) {        let error = e as BusinessError;        console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);      }
} catch (e) { let error = e as BusinessError; console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`); }

// Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); }); }
复制代码

2.3.2 创建一个 KVStoreUtil 工具类


编辑


import { distributedKVStore } from '@kit.ArkData';import { data } from '@kit.TelephonyKit';
export default class KVStoreUtil { private static kvStore: distributedKVStore.SingleKVStore
static setKVStore(kvStore: distributedKVStore.SingleKVStore) { KVStoreUtil.kvStore = kvStore; }
static getKVStore(): distributedKVStore.SingleKVStore { return KVStoreUtil.kvStore; }
/** * 保存数据 * @param key * @param value * @returns */ static insert(key: string, value: string): Promise<string> { return new Promise((resolve, reject) => { KVStoreUtil.kvStore.put(key, value, (err) => { if (err !== undefined) { console.error(`Failed to put data. Code:${err.code},message:${err.message}`); reject(err) } console.info('Succeeded in putting data.'); resolve(key + ':' + value) }); }) }
/** * 获取 * @param key * @returns */ static get(key: string): Promise<string | number | boolean | Uint8Array | void> { return new Promise((resolve, reject) => { KVStoreUtil.kvStore.get(key, (err, data) => { if (err != undefined) { console.error(`Failed to get data. Code:${err.code},message:${err.message}`); reject(err) } console.info(`Succeeded in getting data. Data:${data}`); resolve(key + ':' + data) }); }) }

/** * 删除 * @param key * @returns */ static delete(key: string): Promise<string> { return new Promise((resolve, reject) => { KVStoreUtil.kvStore.delete(key, (err) => { if (err !== undefined) { console.error(`Failed to delete data. Code:${err.code},message:${err.message}`); reject(err) } console.info('Succeeded in deleting data.'); resolve(key) }); }) }}
复制代码

2.3.3 在页面中操作数据库

import KVStoreUtil from '../utils/KVStoreUtil'import { promptAction } from '@kit.ArkUI'import { BusinessError } from '@ohos.base';
@Entry@Componentstruct Index { build() { Column() { Button('插入数据') .onClick(() => { KVStoreUtil.insert('username', '东林').then((data) => { promptAction.showToast({ message: '保存数据成功' + data }) }).catch((error: BusinessError) => { promptAction.showToast({ message: '保存数据失败 ' + error }) })
}).margin({ bottom: 50 })
Button('查询数据') .onClick(() => { KVStoreUtil.get('username').then((data) => { promptAction.showToast({ message: '查询数据成功:' + data }) }).catch((error: BusinessError) => { promptAction.showToast({ message: '查询数据失败 ' + error }) }) }).margin({ bottom: 50 })
Button('删除数据') .onClick(() => { KVStoreUtil.delete('username').then((data) => { promptAction.showToast({ message: '删除数据成功:' + data }) }).catch((error: BusinessError) => { promptAction.showToast({ message: '删除数据失败:' + error }) }) }).margin({ bottom: 50 }) } .height('100%') .width('100%') }}
复制代码


发布于: 2 小时前阅读数: 10
用户头像

享受当下,享受生活,享受成长乐趣! 2025-02-26 加入

鸿蒙、Java、大数据

评论

发布
暂无评论
鸿蒙NEXT开发-应用数据持久化之键值型数据库_东林知识库_InfoQ写作社区