介绍
键值型数据库存储 键值对 形式的数据
应用场景
当需要存储的数据 没有复杂的关系模型,比如:
- 存储商品名称、对应价格
- 存储员工工号、今日是否已出勤
约束限制
设备协同数据库,针对每条记录,
Key的长度≤896 Byte,Value的长度<4 MB。单版本数据库,针对每条记录,
Key的长度≤1 KB,Value的长度<4 MB。每个应用程序最多支持同时打开16个键值型分布式数据库。
键值型数据库事件回调方法中不允许进行阻塞操作,例如修改UI组件。
开发步骤
创建 KVManager 管理器,用于管理数据库
通过 KVManager 创建数据库,本文创建 SingleKVStore 类型数据库
保存数据
根据key获取value
根据key删除数据
通过 KVManager 关闭数据库
导入模块
import { distributedKVStore } from '@kit.ArkData';
创建 KVManager 管理器
创建 KVManager 数据库管理器,用于管理数据库,如:创建数据库、关闭数据库
createKVManager(config: KVManagerConfig): KVManager
参数:
- config:类型:KVManagerConfig,必填,提供KVManager实例的配置信息,包括调用方的包名(不能为空)和用户信息。
返回值:KVManager对象
例子
public initKVManager(bundleName:string):void{
const kvManagerConfig: distributedKVStore.KVManagerConfig = {
context: getContext(),
bundleName: bundleName,
}
try {
this.kvManager = distributedKVStore.createKVManager(kvManagerConfig)
} catch (e) {
let error = e as BusinessError;
console.error(TAG,`创建失败,错误码:${error.code},信息:${error.message}`);
}
}
KVManagerConfig
提供KVManager实例的配置信息,包括调用方的包名和应用的上下文。
包含以下属性:
context:类型:BaseContext,必填,应用的上下文,一般为
getContext()bundleName:类型:string,必填,包名,详见链接
SingleKVStore单版本数据库
单版本数据库,数据不分设备,设备之间修改相同的Key会覆盖
创建数据库
通过 KVManager 对象创建数据库
接口1
通过指定options和storeId,创建并获取分布式键值数据库,使用callback异步回调。
getKVStore<T>(storeId: string, options: Options, callback: AsyncCallback<T>): void
参数:
storeId:类型:
string,必填,数据库唯一标识符,长度不大于 128,且只能包含 字母、数字 或 下划线_。options:类型:
Options,必填,创建分布式键值实例的配置信息。callback:类型:
AsyncCallback<T>,必填,回调函数。返回创建的分布式键值数据库实例(根据kvStoreType的不同,可以创建SingleKVStore实例和DeviceKVStore实例)。
例子
public initKVStore(storeId:string){
const options: distributedKVStore.Options = {
createIfMissing: true, // 当数据库文件不存在时创建数据库
encrypt: false, // 数据库文件不加密
backup: false, // 不备份
autoSync: false, // 不自动同步
kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, // 单版本数据库。 数据不分设备,设备之间修改相同的Key会覆盖
securityLevel: distributedKVStore.SecurityLevel.S1, // 安全级别为低级别,数据的泄露、篡改、破坏、销毁可能会给个人或组织导致 有限的不利影响。
};
this.kvManager.getKVStore(storeId, options, (err: BusinessError, store: distributedKVStore.SingleKVStore) => {
if (err) {
console.error(TAG,`创建 KVStore 失败,错误码: ${err.code},信息:${err.message}`);
return;
}
this.kvStore = store;
});
}
Options
用于提供创建数据库的配置信息。有以下属性:
createIfMissing:类型:boolean,当数据库文件不存在时是否创建数据库,默认为true,即创建。
encrypt:类型:boolean,设置数据库文件是否加密,默认为false,即不加密。
backup:类型:boolean,设置数据库文件是否备份,默认为true,即备份。
autoSync:类型:boolean,设置数据库是否支持跨设备自动同步。默认为false,即只支持手动同步。配置为true,即只支持在跨设备Call调用实现的多端协同中生效,其他场景无法生效。
需要权限: ohos.permission.DISTRIBUTED_DATASYNCkvStoreType:类型:KVStoreType,设置要创建的数据库类型,默认为
DEVICE_COLLABORATION,即多设备协同数据库。securityLevel:类型:SecurityLevel,必填,设置数据库安全级别。
schema:类型:Schema,设置定义存储在数据库中的值,默认为
undefined,即不使用Schema。
KVStoreType
分布式键值数据库类型枚举
DEVICE_COLLABORATION:表示多设备协同数据库。数据库特点: 数据以设备的维度管理,不存在冲突;支持按照设备的维度查询数据。
SINGLE_VERSION:表示单版本数据库。数据库特点: 数据不分设备,设备之间修改相同的Key会覆盖。
SecurityLevel
数据库的安全级别枚举。
S1:表示数据库的安全级别为低级别,数据的泄露、篡改、破坏、销毁可能会给个人或组织导致 有限的不利影响。
例如,性别、国籍,用户申请记录等。S2:表示数据库的安全级别为中级别,数据的泄露、篡改、破坏、销毁可能会给个人或组织导致 严重的不利影响。
例如,个人详细通信地址,姓名昵称等。S3:表示数据库的安全级别为高级别,数据的泄露、篡改、破坏、销毁可能会给个人或组织导致 严峻的不利影响。
例如,个人实时精确定位信息、运动轨迹等。S4:表示数据库的安全级别为关键级别,业界法律法规中定义的特殊数据类型,涉及个人的最私密领域的信息或者一旦泄露、篡改、破坏、销毁可能会给个人或组织造成 重大的不利影响。
例如,政治观点、宗教、和哲学信仰、工会成员资格、基因数据、生物信息、健康和性生活状况、性取向等或设备认证鉴权、个人的信用卡等财务信息。
接口2
通过指定options和storeId,创建并获取分布式键值数据库,使用Promise异步回调。
getKVStore<T>(storeId: string, options: Options): Promise<T>
参数:类似接口1
返回值:类型:Promise<T>,Promise对象。返回创建的分布式键值数据库实例(根据kvStoreType的不同,可以创建SingleKVStore 实例和 DeviceKVStore 实例。
关闭数据库
接口1
通过storeId的值关闭指定的分布式键值数据库,使用callback异步回调
closeKVStore(appId: string, storeId: string, callback: AsyncCallback<void>): void
参数:
appId:类型:
string,必填,应用的 BundleName,不可为空且长度不大于256。storeId:类型:
string,必填,要关闭的数据库唯一标识符,长度不大于 128,且只能包含字母数字或下划线_。callback:类型:
AsyncCallback<void>,必填,回调函数。当要关闭的数据库成功关闭,err为undefined,否则为错误对象。
例子
public close(bundleName:string,storeId:string){
this.kvManager.closeKVStore(bundleName, storeId, (err: BusinessError)=> {
if (err != undefined) {
console.error(TAG,`关闭数据库失败,错误码:${err.code},信息: ${err.message}`);
return;
}
});
}
接口2
通过storeId的值关闭指定的分布式键值数据库,使用Promise异步回调。
closeKVStore(appId: string, storeId: string): Promise<void>
参数:同上
返回值:Promise<void>,无返回结果的Promise对象。
保存数据
接口1
添加指定类型键值对到数据库,使用callback异步回调。
put(key: string, value: Uint8Array | string | number | boolean, callback: AsyncCallback<void>): void
参数:
key:类型:
string,必填,要添加数据的Key,不能为空且长度不大于128。value:类型:
Uint8Array | string | number | boolean,必填,要添加数据的value,长度不大于128。callback:类型:
AsyncCallback<void>,必填,回调函数。数据添加成功,err为undefined,否则为错误对象。
例子
public put(key:string,value:string){
try {
this.kvStore.put(key, value, (err: BusinessError) => {
if (err != undefined) {
console.error(TAG,`保存数据发生错误,错误码:${err.code},信息:${err.message}`);
return;
}
});
} catch (error) {
let err = error as BusinessError;
console.error(TAG,`保存数据发生错误,错误码:${err.code},信息:${err.message}`);
}
}
接口2
添加指定类型键值对到数据库,使用Promise异步回调。
put(key: string, value: Uint8Array | string | number | boolean): Promise<void>
参数:同上
返回值: 类型Promise<void>,无返回结果的Promise对象。
根据key获取value
接口1
获取指定键的值,使用callback异步回调。
get(key: string, callback: AsyncCallback<boolean | string | number | Uint8Array>): void
参数:
key:类型:string,必填,要查询数据的Key,不能为空且长度不大于MAX_KEY_LENGTH。
callback:类型:
AsyncCallback<boolean | string | number | Uint8Array>,必填,回调函数。返回获取查询的值。
例子
public async get(key:string){
let data!:boolean | string | number | Uint8Array
try {
data = await this.kvStore.get(key)
}catch (error) {
let err = error as BusinessError;
console.error(TAG,`获取数据发生错误,错误码:${err.code},信息:${err.message}`);
}
return data
}
接口2
获取指定键的值,使用Promise异步回调。
get(key: string): Promise<boolean | string | number | Uint8Array>
参数:
- key:类型:
string,必填,要查询数据的Key,不能为空且长度不大于128
返回值: Promise<Uint8Array | string | boolean | number>,Promise对象。返回获取查询的值。
根据key删除数据
接口1
从数据库中删除指定键值的数据,使用callback异步回调。
delete(key: string, callback: AsyncCallback<void>): void
参数:
key:类型:string,必填,要删除数据的Key,不能为空且长度不大于 128
callback:类型:
AsyncCallback<void>,必填,回调函数。删除指定的数据成功,err为undefined,否则为错误对象。
接口2
从数据库中删除指定键值的数据,使用Promise异步回调。
delete(key: string): Promise<void>
参数:同上
返回值: Promise<void>,无返回结果的Promise对象。
例子
public delete(key:string){
this.kvStore.delete(key)
.catch((err: BusinessError) => {
console.error(TAG,`删除数据失败,错误码:${err.code},信息:${err.message}`);
});
}
完整代码
UI
import { BusinessError } from '@kit.BasicServicesKit';
import KVManagerUtil from './KVManagerUtil'
const kvMgr:KVManagerUtil = new KVManagerUtil()
// 包名
const bundleName = 'com.example.myapplication2'
// 数据库名
const storeName = 's_user'
@Entry
@Component
struct KVManagerPage {
@State putKey :string = ''
@State putValue :string = ''
@State getKey :string = ''
@State delKey :string = ''
@State msg:string = ''
build() {
Column() {
Button("创建kvManager")
.fontSize(20)
.height(50)
.onClick( e=>{
kvMgr.initKVManager(bundleName)
})
Button("获取SingleKVStore")
.fontSize(20)
.height(50)
.onClick( e=>{
kvMgr.initKVStore(storeName)
})
Row(){
Text("key:")
.fontSize(20)
TextInput({
text:$$this.putKey
})
}
Row(){
Text("value:")
.fontSize(20)
TextInput({
text:$$this.putValue
})
}
Button("保存数据")
.fontSize(20)
.height(50)
.onClick( e=>{
kvMgr.put(this.putKey,this.putValue)
})
Row(){
Text("key:")
.fontSize(20)
TextInput({
text:$$this.getKey
})
}
Row(){
Text("结果:")
.fontSize(20)
Text(this.msg)
.fontSize(30)
.height(50)
}
Button("获取数据")
.fontSize(20)
.height(50)
.onClick( async e=>{
const res = await kvMgr.get(this.getKey) as string
this.msg = res
})
Row(){
Text("key:")
.fontSize(20)
TextInput({
text:$$this.delKey
})
}
Button("删除数据")
.fontSize(20)
.height(50)
.onClick( e=>{
kvMgr.delete(this.delKey)
})
Text("关闭数据库")
.fontSize(20)
.height(50)
.onClick( e=>{
kvMgr.close(bundleName,storeName)
})
}
.height('100%')
.width('100%')
}
}
工具类
在 ets 下创建包 utils,然后创建 KVStoreUtils.ets,内如如下:
import { distributedKVStore } from '@kit.ArkData';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = "KVManagerUtil--"
export default class KVManagerUtil{
kvManager !: distributedKVStore.KVManager;
kvStore !: distributedKVStore.SingleKVStore
constructor() {
}
/**
*
* @param bundleName 包名,如:com.example.myapplication2
*/
public initKVManager(bundleName:string):void{
const kvManagerConfig: distributedKVStore.KVManagerConfig = {
context: getContext(),
bundleName: bundleName,
}
try {
this.kvManager = distributedKVStore.createKVManager(kvManagerConfig)
} catch (e) {
let error = e as BusinessError;
console.error(TAG,`创建失败,错误码:${error.code},信息:${error.message}`);
}
}
public initKVStore(storeId:string){
const options: distributedKVStore.Options = {
createIfMissing: true, // 当数据库文件不存在时创建数据库
encrypt: false, // 数据库文件不加密
backup: false, // 不备份
autoSync: false, // 不自动同步
kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, // 单版本数据库。 数据不分设备,设备之间修改相同的Key会覆盖
securityLevel: distributedKVStore.SecurityLevel.S1, // 安全级别为低级别,数据的泄露、篡改、破坏、销毁可能会给个人或组织导致 有限的不利影响。
};
this.kvManager.getKVStore(storeId, options, (err: BusinessError, store: distributedKVStore.SingleKVStore) => {
if (err) {
console.error(TAG,`创建 KVStore 失败,错误码: ${err.code},信息:${err.message}`);
return;
}
this.kvStore = store;
});
}
public put(key:string,value:string){
try {
this.kvStore.put(key, value, (err: BusinessError) => {
if (err != undefined) {
console.error(TAG,`保存数据发生错误,错误码:${err.code},信息:${err.message}`);
return;
}
});
} catch (error) {
let err = error as BusinessError;
console.error(TAG,`保存数据发生错误,错误码:${err.code},信息:${err.message}`);
}
}
public async get(key:string){
let data!:boolean | string | number | Uint8Array
try {
data = await this.kvStore.get(key)
}catch (error) {
let err = error as BusinessError;
console.error(TAG,`获取数据发生错误,错误码:${err.code},信息:${err.message}`);
}
return data
}
public delete(key:string){
this.kvStore.delete(key)
.catch((err: BusinessError) => {
console.error(TAG,`删除数据失败,错误码:${err.code},信息:${err.message}`);
});
}
public close(bundleName:string,storeId:string){
this.kvManager.closeKVStore(bundleName, storeId, (err: BusinessError)=> {
if (err != undefined) {
console.error(TAG,`关闭数据库失败,错误码:${err.code},信息: ${err.message}`);
return;
}
});
}
}
