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%')
}
}