1# 通过键值型数据库实现数据持久化 2 3 4## 场景介绍 5 6键值型数据库存储键值对形式的数据,当需要存储的数据没有复杂的关系模型,比如存储商品名称及对应价格、员工工号及今日是否已出勤等,由于数据复杂度低,更容易兼容不同数据库版本和设备类型,因此推荐使用键值型数据库持久化此类数据。 7 8 9## 约束限制 10 11- 设备协同数据库,针对每条记录,Key的长度≤896 Byte,Value的长度<4 MB。 12 13- 单版本数据库,针对每条记录,Key的长度≤1 KB,Value的长度<4 MB。 14 15- 每个应用程序最多支持同时打开16个键值型分布式数据库。 16 17- 键值型数据库事件回调方法中不允许进行阻塞操作,例如修改UI组件。 18 19 20## 接口说明 21 22以下是键值型数据库持久化功能的相关接口,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下表均以callback形式为例,更多接口及使用方式请见[分布式键值数据库](../reference/apis-arkdata/js-apis-distributedKVStore.md)。 23 24| 接口名称 | 描述 | 25| -------- | -------- | 26| createKVManager(config: KVManagerConfig): KVManager | 创建一个KVManager对象实例,用于管理数据库对象。 | 27| getKVStore<T>(storeId: string, options: Options, callback: AsyncCallback<T>): void | 指定options和storeId,创建并得到指定类型的KVStore数据库。 | 28| put(key: string, value: Uint8Array \| string \| number \| boolean, callback: AsyncCallback<void>): void | 添加指定类型的键值对到数据库。 | 29| get(key: string, callback: AsyncCallback\<boolean \| string \| number \| Uint8Array>): void | 获取指定键的值。 | 30| delete(key: string, callback: AsyncCallback<void>): void | 从数据库中删除指定键值的数据。 | 31| closeKVStore(appId: string, storeId: string, callback: AsyncCallback<void>): void | 通过storeId的值关闭指定的分布式键值数据库。 | 32| deleteKVStore(appId: string, storeId: string, callback: AsyncCallback<void>): void | 通过storeId的值删除指定的分布式键值数据库。 | 33 34 35## 开发步骤 36 371. 若要使用键值型数据库,首先要获取一个KVManager实例,用于管理数据库对象。示例代码如下所示: 38 39 Stage模型示例: 40 41 42 ```js 43 // 导入模块 44 import { distributedKVStore } from '@kit.ArkData'; 45 46 // Stage模型 47 import { window } from '@kit.ArkUI'; 48 import { UIAbility } from '@kit.AbilityKit'; 49 import { BusinessError } from '@kit.BasicServicesKit'; 50 51 let kvManager: distributedKVStore.KVManager | undefined = undefined; 52 53 export default class EntryAbility extends UIAbility { 54 onCreate() { 55 let context = this.context; 56 const kvManagerConfig: distributedKVStore.KVManagerConfig = { 57 context: context, 58 bundleName: 'com.example.datamanagertest' 59 }; 60 try { 61 // 创建KVManager实例 62 kvManager = distributedKVStore.createKVManager(kvManagerConfig); 63 console.info('Succeeded in creating KVManager.'); 64 // 继续创建获取数据库 65 } catch (e) { 66 let error = e as BusinessError; 67 console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`); 68 } 69 } 70 } 71 if (kvManager !== undefined) { 72 kvManager = kvManager as distributedKVStore.KVManager; 73 //进行后续操作 74 //... 75 } 76 ``` 77 78 FA模型示例: 79 80 81 ```js 82 // 导入模块 83 import { distributedKVStore } from '@kit.ArkData'; 84 85 // FA模型 86 import { featureAbility } from '@kit.AbilityKit'; 87 import { BusinessError } from '@kit.BasicServicesKit'; 88 89 let kvManager: distributedKVStore.KVManager | undefined = undefined; 90 let context = featureAbility.getContext(); // 获取context 91 const kvManagerConfig: distributedKVStore.KVManagerConfig = { 92 context: context, 93 bundleName: 'com.example.datamanagertest' 94 }; 95 try { 96 kvManager = distributedKVStore.createKVManager(kvManagerConfig); 97 console.info('Succeeded in creating KVManager.'); 98 // 继续创建获取数据库 99 } catch (e) { 100 let error = e as BusinessError; 101 console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`); 102 } 103 if (kvManager !== undefined) { 104 kvManager = kvManager as distributedKVStore.KVManager; 105 //进行后续操作 106 //... 107 } 108 109 ``` 110 1112. 创建并获取键值数据库。示例代码如下所示: 112 113 ```js 114 let kvStore: distributedKVStore.SingleKVStore | undefined = undefined; 115 try { 116 const options: distributedKVStore.Options = { 117 createIfMissing: true, 118 encrypt: false, 119 backup: false, 120 autoSync: false, 121 // kvStoreType不填时,默认创建多设备协同数据库 122 kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, 123 // 多设备协同数据库:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION, 124 securityLevel: distributedKVStore.SecurityLevel.S3 125 }; 126 kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', options, (err, store: distributedKVStore.SingleKVStore) => { 127 if (err) { 128 console.error(`Failed to get KVStore: Code:${err.code},message:${err.message}`); 129 return; 130 } 131 console.info('Succeeded in getting KVStore.'); 132 kvStore = store; 133 // 请确保获取到键值数据库实例后,再进行相关数据操作 134 }); 135 } catch (e) { 136 let error = e as BusinessError; 137 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 138 } 139 if (kvStore !== undefined) { 140 kvStore = kvStore as distributedKVStore.SingleKVStore; 141 //进行后续操作 142 //... 143 } 144 ``` 145 1463. 调用put()方法向键值数据库中插入数据。示例代码如下所示: 147 148 ```js 149 const KEY_TEST_STRING_ELEMENT = 'key_test_string'; 150 const VALUE_TEST_STRING_ELEMENT = 'value_test_string'; 151 try { 152 kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => { 153 if (err !== undefined) { 154 console.error(`Failed to put data. Code:${err.code},message:${err.message}`); 155 return; 156 } 157 console.info('Succeeded in putting data.'); 158 }); 159 } catch (e) { 160 let error = e as BusinessError; 161 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 162 } 163 ``` 164 165 > **说明:** 166 > 167 > 当Key值存在时,put()方法会修改其值,否则新增一条数据。 168 1694. 调用get()方法获取指定键的值。示例代码如下所示: 170 171 ```js 172 try { 173 kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => { 174 if (err !== undefined) { 175 console.error(`Failed to put data. Code:${err.code},message:${err.message}`); 176 return; 177 } 178 console.info('Succeeded in putting data.'); 179 kvStore = kvStore as distributedKVStore.SingleKVStore; 180 kvStore.get(KEY_TEST_STRING_ELEMENT, (err, data) => { 181 if (err != undefined) { 182 console.error(`Failed to get data. Code:${err.code},message:${err.message}`); 183 return; 184 } 185 console.info(`Succeeded in getting data. Data:${data}`); 186 }); 187 }); 188 } catch (e) { 189 let error = e as BusinessError; 190 console.error(`Failed to get data. Code:${error.code},message:${error.message}`); 191 } 192 ``` 193 1945. 调用delete()方法删除指定键值的数据。示例代码如下所示: 195 196 ```js 197 try { 198 kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => { 199 if (err !== undefined) { 200 console.error(`Failed to put data. Code:${err.code},message:${err.message}`); 201 return; 202 } 203 console.info('Succeeded in putting data.'); 204 kvStore = kvStore as distributedKVStore.SingleKVStore; 205 kvStore.delete(KEY_TEST_STRING_ELEMENT, (err) => { 206 if (err !== undefined) { 207 console.error(`Failed to delete data. Code:${err.code},message:${err.message}`); 208 return; 209 } 210 console.info('Succeeded in deleting data.'); 211 }); 212 }); 213 } catch (e) { 214 let error = e as BusinessError; 215 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 216 } 217 ``` 218 2196. 通过storeId的值关闭指定的分布式键值数据库。示例代码如下所示: 220 221 ```js 222 try { 223 kvStore = undefined; 224 kvManager.closeKVStore('appId', 'storeId', (err: BusinessError)=> { 225 if (err) { 226 console.error(`Failed to close KVStore.code is ${err.code},message is ${err.message}`); 227 return; 228 } 229 console.info('Succeeded in closing KVStore'); 230 }); 231 } catch (e) { 232 let error = e as BusinessError; 233 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 234 } 235 ``` 236 2377. 通过storeId的值删除指定的分布式键值数据库。示例代码如下所示: 238 239 ```js 240 try { 241 kvStore = undefined; 242 kvManager.deleteKVStore('appId', 'storeId', (err: BusinessError)=> { 243 if (err) { 244 console.error(`Failed to close KVStore.code is ${err.code},message is ${err.message}`); 245 return; 246 } 247 console.info('Succeeded in closing KVStore'); 248 }); 249 } catch (e) { 250 let error = e as BusinessError; 251 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 252 } 253 ```