database-mdds-guidelines.md 11.1 KB
Newer Older
Z
zengyawen 已提交
1 2 3 4 5 6 7 8 9
# 分布式数据服务开发指导

## 场景介绍

分布式数据服务主要实现用户设备中应用程序数据内容的分布式同步。当设备1上的应用A在分布式数据库中增、删、改数据后,设备2上的应用A也可以获取到该数据库变化。可在分布式图库、信息、通讯录、文件管理器等场景中使用。


## 接口说明

Q
qing 已提交
10
分布式数据相关功能接口请见[分布式键值数据库](../reference/apis/js-apis-distributedKVStore.md)
Z
zengyawen 已提交
11 12 13

**表1** 分布式数据服务关键API功能介绍

Q
qing 已提交
14 15 16
| 接口名称                                                     | 描述                                                         |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| createKVManager(config: KVManagerConfig, callback: AsyncCallback&lt;KVManager&gt;): void<br/>createKVManager(config: KVManagerConfig): Promise&lt;KVManager> | 创建一个`KVManager`对象实例,用于管理数据库对象。            |
17
| getKVStore&lt;T extends KVStore&gt;(storeId: string, options: Options, callback: AsyncCallback&lt;T&gt;): void<br/>getKVStore&lt;T extends KVStore&gt;(storeId: string, options: Options): Promise&lt;T&gt; | 指定`Options``storeId`,创建并获取指定类型`KVStore`数据库。 |
Q
qing 已提交
18 19 20 21 22
| put(key: string, value: Uint8Array\|string\|number\|boolean, callback: AsyncCallback&lt;void&gt;): void<br/>put(key: string, value: Uint8Array\|string\|number\|boolean): Promise&lt;void> | 插入和更新数据。                                             |
| delete(key: string, callback: AsyncCallback&lt;void&gt;): void<br/>delete(key: string): Promise&lt;void> | 删除数据。                                                   |
| get(key: string, callback: AsyncCallback&lt;Uint8Array\|string\|boolean\|number&gt;): void<br/>get(key: string): Promise&lt;Uint8Array\|string\|boolean\|number> | 查询数据。                                                   |
| on(event: 'dataChange', type: SubscribeType, observer: Callback&lt;ChangeNotification&gt;): void<br/>on(event: 'syncComplete', syncCallback: Callback&lt;Array&lt;[string,number]&gt;&gt;): void | 订阅数据库中数据的变化。                                     |
| sync(deviceIdList: string[], mode: SyncMode, allowedDelayMs?: number): void | 在手动模式下,触发数据库同步。                               |
Z
zengyawen 已提交
23

Z
zengyawen 已提交
24 25 26 27 28
## 开发步骤

以单版本分布式数据库为例,说明开发步骤。

1. 导入模块。
29

30
   ```js
Q
qing 已提交
31
   import distributedKVStore from '@ohos.data.distributedKVStore';
Z
zengyawen 已提交
32
   ```
Q
qing 已提交
33

34 35 36 37 38
2. 请求权限(同步操作时进行该步骤)。

   需要在`config.json`文件里进行配置请求权限(FA模型),示例代码如下:

    ```json
Q
qing 已提交
39 40 41 42 43 44 45 46 47
    {
      "module": {
          "reqPermissions": [
              {
                 "name": "ohos.permission.DISTRIBUTED_DATASYNC"
              }
          ]
      }
    }
48
    ```
Q
qing 已提交
49

50 51 52 53 54
   Stage模型下的权限请求请参见[权限声明-Stage模型](../security/accesstoken-guidelines.md#stage模型)

   这个权限还需要在应用首次启动的时候弹窗获取用户授权,可以通过如下代码实现:

    ```js
55
    // FA模型
56
    import featureAbility from '@ohos.ability.featureAbility';
Q
qing 已提交
57
   
58
    function grantPermission() {
59 60 61 62 63 64 65
    console.info('grantPermission');
    let context = featureAbility.getContext();
    context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666).then((data) => {
        console.info('success: ${data}');
    }).catch((error) => {
        console.info('failed: ${error}');
    })
66
    }
Q
qing 已提交
67
   
68
    grantPermission();
Q
qing 已提交
69
   
70
    // Stage模型
71
    import UIAbility from '@ohos.app.ability.UIAbility';
Q
qing 已提交
72
   
73
    let context = null;
W
wangkai 已提交
74 75 76

    class EntryAbility  extends UIAbility  {
      onWindowStageCreate(windowStage) {
77
        let context = this.context;
W
wangkai 已提交
78
      }
79
    }
W
wangkai 已提交
80 81 82 83

    function grantPermission() {
      let permissions = ['ohos.permission.DISTRIBUTED_DATASYNC'];
      context.requestPermissionsFromUser(permissions).then((data) => {
84
        console.log('success: ${data}');
W
wangkai 已提交
85
      }).catch((error) => {
86
        console.log('failed: ${error}');
W
wangkai 已提交
87
      });
88
    }
W
wangkai 已提交
89

90
    grantPermission();
91 92 93
    ```

3. 根据配置构造分布式数据库管理类实例。
94

95
   1. 根据应用上下文创建`kvManagerConfig`对象。
Z
zengyawen 已提交
96 97 98
   2. 创建分布式数据库管理器实例。

   以下为创建分布式数据库管理器的代码示例:
99

100
   ```js
101 102 103
   // FA模型获取context
   import featureAbility from '@ohos.ability.featureAbility';
   let context = featureAbility.getContext();
Q
qing 已提交
104
   
105
   // Stage模型获取context
106
   import UIAbility from '@ohos.app.ability.UIAbility';
107
   let context = null;
108
   class EntryAbility extends UIAbility {
109 110 111 112
      onWindowStageCreate(windowStage){
        context = this.context;
      }
   }
Q
qing 已提交
113
   
Z
zengyawen 已提交
114 115
   let kvManager;
   try {
116 117
     const kvManagerConfig = {
       bundleName: 'com.example.datamanagertest',
Q
qing 已提交
118
       context:context,
119
     }
Q
qing 已提交
120
     distributedKVStore.createKVManager(kvManagerConfig, function (err, manager) {
121
       if (err) {
Q
qing 已提交
122
         console.error(`Failed to createKVManager.code is ${err.code},message is ${err.message}`);
123 124
         return;
       }
Q
qing 已提交
125
       console.log('Succeeded in creating KVManager');
126 127
       kvManager = manager;
     });
Z
zengyawen 已提交
128
   } catch (e) {
Q
qing 已提交
129
     console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`);
Z
zengyawen 已提交
130 131 132
   }
   ```

133
4. 获取/创建分布式数据库。
134

Z
zengyawen 已提交
135
   1. 声明需要创建的分布式数据库ID描述。
136
   2. 创建分布式数据库,建议关闭自动同步功能(`autoSync:false`),需要同步时主动调用`sync`接口。
Z
zengyawen 已提交
137 138

   以下为创建分布式数据库的代码示例:
139

140
   ```js
Z
zengyawen 已提交
141 142
   let kvStore;
   try {
143 144 145 146 147
     const options = {
       createIfMissing: true,
       encrypt: false,
       backup: false,
       autoSync: false,
Q
qing 已提交
148 149
       kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
       securityLevel: distributedKVStore.SecurityLevel.S1
150 151 152
     };
     kvManager.getKVStore('storeId', options, function (err, store) {
       if (err) {
Q
qing 已提交
153
         console.error(`Failed to get KVStore: code is ${err.code},message is ${err.message}`);
154 155
         return;
       }
Q
qing 已提交
156
       console.log('Succeeded in getting KVStore');
157 158
       kvStore = store;
     });
Z
zengyawen 已提交
159
   } catch (e) {
Q
qing 已提交
160
     console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`);
Z
zengyawen 已提交
161 162 163
   }
   ```

164 165 166
   > **说明:**
   >
   > 组网设备间同步数据的场景,建议在应用启动时打开分布式数据库,获取数据库的句柄。在该句柄(如示例中的`kvStore`)的生命周期内无需重复创建数据库,可直接使用句柄对数据库进行数据的插入等操作。
Q
qing 已提交
167

168
5. 订阅分布式数据变化。
169

Z
zengyawen 已提交
170
   以下为订阅单版本分布式数据库数据变化通知的代码示例:
171

172
   ```js
Q
qing 已提交
173 174 175 176 177 178 179
   try{
       kvStore.on('dataChange', distributedKVStore.SubscribeType.SUBSCRIBE_TYPE_ALL, function (data) {
           console.log(`dataChange callback call data: ${data}`);
       });
   }catch(e){
       console.error(`An unexpected error occured.code is ${e.code},message is ${e.message}`);
   }
Z
zengyawen 已提交
180 181
   ```

182
6. 将数据写入分布式数据库。
183

184
   1. 构造需要写入分布式数据库的`Key`(键)和`Value`(值)。
Z
zengyawen 已提交
185 186 187 188
   2. 将键值数据写入分布式数据库。

   以下为将字符串类型键值数据写入分布式数据库的代码示例:

189
   ```js
Z
zengyawen 已提交
190 191 192
   const KEY_TEST_STRING_ELEMENT = 'key_test_string';
   const VALUE_TEST_STRING_ELEMENT = 'value-test-string';
   try {
Q
qing 已提交
193
       kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) {
Z
zengyawen 已提交
194
           if (err != undefined) {
Q
qing 已提交
195
               console.error(`Failed to put.code is ${err.code},message is ${err.message}`);
Z
zengyawen 已提交
196 197
               return;
           }
Q
qing 已提交
198
           console.log("Succeeded in putting");
Z
zengyawen 已提交
199
       });
Q
qing 已提交
200 201
   }catch (e) {
       console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`);
Z
zengyawen 已提交
202 203 204
   }
   ```

205
7. 查询分布式数据库数据。
206

207
   1. 构造需要从单版本分布式数据库中查询的`Key`(键)。
Z
zengyawen 已提交
208 209 210
   2. 从单版本分布式数据库中获取数据。

   以下为从分布式数据库中查询字符串类型数据的代码示例:
211

212
   ```js
Z
zengyawen 已提交
213 214 215
   const KEY_TEST_STRING_ELEMENT = 'key_test_string';
   const VALUE_TEST_STRING_ELEMENT = 'value-test-string';
   try {
Q
qing 已提交
216 217
       kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) {
           if (err != undefined) {
Q
qing 已提交
218
               console.error(`Failed to put.code is ${err.code},message is ${err.message}`);
Q
qing 已提交
219 220 221 222
               return;
           }
           console.log("Succeeded in putting");
           kvStore.get(KEY_TEST_STRING_ELEMENT, function (err,data) {
Z
zengyawen 已提交
223
           if (err != undefined) {
Q
qing 已提交
224
               console.error(`Failed to get.code is ${err.code},message is ${err.message}`);
Z
zengyawen 已提交
225 226
               return;
           }
Q
qing 已提交
227
               console.log(`Succeeded in getting data:${data}`);
Z
zengyawen 已提交
228 229
           });
       });
Q
qing 已提交
230
   }catch (e) {
Q
qing 已提交
231
       console.error(`Failed to get.code is ${e.code},message is ${e.message}`);
Z
zengyawen 已提交
232 233 234
   }
   ```

235
8. 同步数据到其他设备。
236

237
   选择同一组网环境下的设备以及同步模式,进行数据同步。
Z
zengyawen 已提交
238

239 240 241
   > **说明**:
   >
   > 其中`deviceManager`模块的接口均为系统接口。
Q
qing 已提交
242

243
   以下为单版本分布式数据库进行数据同步的代码示例:
244

245
   ```js
Z
zengyawen 已提交
246 247 248 249
   import deviceManager from '@ohos.distributedHardware.deviceManager';
   
   let devManager;
   // create deviceManager
250
   deviceManager.createDeviceManager('bundleName', (err, value) => {
Z
zengyawen 已提交
251 252
       if (!err) {
           devManager = value;
253
           // deviceIds由deviceManager调用getTrustedDeviceListSync方法得到
254 255
           let deviceIds = [];
           if (devManager != null) {
256 257 258
               var devices = devManager.getTrustedDeviceListSync();
               for (var i = 0; i < devices.length; i++) {
                   deviceIds[i] = devices[i].deviceId;
259 260
               }
           }
261
           try{
262
               // 1000表示最大延迟时间为1000ms
Q
qing 已提交
263
               kvStore.sync(deviceIds, distributedKVStore.SyncMode.PUSH_ONLY, 1000);
264
           } catch (e) {
Q
qing 已提交
265
                console.error(`An unexpected error occurred. code is ${e.code},message is ${e.message}`);
266
           }
Z
zengyawen 已提交
267 268 269
       }
   });
   ```
Q
qing 已提交
270

271
## 相关实例
272

273
针对分布式数据开发,有以下相关实例可供参考:
274

275
- [`DistributedCalc`:分布式计算器(JS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/common/DistributeCalc)
Q
qing 已提交
276 277 278 279
- [`DistributedCalc`:分布式计算器(ArkTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/Preset/DistributeCalc)
- [`DistributedDataGobang`:分布式五子棋(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/data/DistributedDataGobang)
- [`DDMQuery`:结果集与谓词(ArkTS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/master/data/DDMQuery)
- [`KvStore`:分布式数据库(ArkTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/data/Kvstore)
280
- [分布式数据库(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/Data/JsDistributedData)