• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 关系型数据库开发指导
2
3## 场景介绍
4
5关系型数据库是在SQLite基础上实现的本地数据操作机制,提供给用户无需编写原生SQL语句就能进行数据增删改查的方法,同时也支持原生SQL语句操作。
6
7
8## 接口说明
9
10以下是关系型数据库的常用接口说明,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下表均以Promise形式为例,更多接口及使用方式请见[关系型数据库](../reference/apis/js-apis-data-relationalStore.md)。
11
12### 数据库的创建和删除
13
14关系型数据库提供了数据库创建方式,以及对应的删除接口,涉及的API如下所示。
15
16**表1** 数据库创建和删除API
17
18| 接口名                                                       | 描述                                                         |
19| ------------------------------------------------------------ | ------------------------------------------------------------ |
20| getRdbStore(context: Context, config: StoreConfig): Promise&lt;RdbStore&gt; | 获得一个相关的RdbStore,操作关系型数据库,用户可以根据自己的需求配置RdbStore的参数,然后通过RdbStore调用相关接口可以执行相关的数据操作,使用Promise异步回调。<br/>-context:应用上下文。<br/>-config:与此RDB存储相关的数据库配置。 |
21| deleteRdbStore(context: Context, name: string): Promise&lt;void&gt; | 使用指定的数据库文件配置删除数据库,使用Promise异步回调。<br/>-context:应用上下文。<br/>-name:数据库名称。 |
22
23### 数据库的增删改查
24
25关系型数据库提供对本地数据增删改查操作的能力,相关API如下所示。
26
27- **新增**
28
29  关系型数据库提供了插入数据的接口,通过ValuesBucket输入要存储的数据,通过返回值判断是否插入成功,插入成功时返回最新插入数据所在的行号,失败时则返回-1。
30
31  **表2** 数据库插入API
32
33
34  | 类名       | 接口名                                                       | 描述                                                         |
35  | ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
36  | RdbStore | insert(table: string, values: ValuesBucket): Promise&lt;number&gt; | 向目标表中插入一行数据,使用Promise异步回调。<br>如果操作成功,返回行ID;否则返回-1。<br/>-table:指定的目标表名。<br/>-values:表示要插入到表中的数据行。 |
37
38- **更新**
39
40  调用更新接口,传入要更新的数据,并通过RdbPredicates指定更新条件。该接口的返回值表示更新操作影响的行数。如果更新失败,则返回0。
41
42  **表3** 数据库更新API
43
44
45  | 类名       | 接口名                                                       | 描述                                                         |
46  | ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
47  | RdbStore | update(values: ValuesBucket, predicates: RdbPredicates): Promise&lt;number&gt; | 根据RdbPredicates的指定实例对象更新数据库中的数据,使用Promise异步回调。<br>返回受影响的行数。<br/>-values:以ValuesBucket存储的要更新的数据。<br/>-predicates:表示RdbPredicates的实例对象指定的更新条件。 |
48
49- **删除**
50
51  调用删除接口,通过RdbPredicates指定删除条件。该接口的返回值表示删除的数据行数,可根据此值判断是否删除成功。如果删除失败,则返回0。
52
53  **表4** 数据库删除API
54
55
56  | 类名       | 接口名                                                     | 描述                                                         |
57  | ---------- | ---------------------------------------------------------- | ------------------------------------------------------------ |
58  | RdbStore | delete(predicates: RdbPredicates): Promise&lt;number&gt; | 根据RdbPredicates的指定实例对象从数据库中删除数据,使用Promise异步回调。<br>返回受影响的行数。 <br/>-predicates:RdbPredicates的实例对象指定的删除条件。 |
59
60- **查询**
61
62  关系型数据库提供了两种查询数据的方式:
63
64  - 直接调用查询接口。使用该接口,会将包含查询条件的谓词自动拼接成完整的SQL语句进行查询操作,无需用户传入原生的SQL语句。
65  - 执行原生的SQL语句进行查询操作。
66
67  **表5** 数据库查询API
68
69  | 类名       | 接口名                                                       | 描述                                                         |
70  | ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
71  | RdbStore | query(predicates: RdbPredicates, columns?: Array&lt;string&gt;): Promise&lt;ResultSet&gt; | 根据指定条件查询数据库中的数据,使用Promise异步回调。<br/>-predicates:表示RdbPredicates的实例对象指定的查询条件。<br/>-columns:表示要查询的列。如果值为空,则查询应用于所有列。 |
72  | RdbStore | querySql(sql: string, bindArgs?: Array&lt;ValueType&gt;): Promise&lt;ResultSet&gt; | 根据指定SQL语句查询数据库中的数据,使用Promise异步回调。<br/>-sql:指定要查询的SQL语句。<br/>-bindArgs:SQL语句中参数的值。 |
73  | RdbStore | remoteQuery(device: string, table: string, predicates: RdbPredicates, columns: Array&lt;string&gt;): Promise&lt;ResultSet&gt; | 根据指定条件查询指定远程设备数据库中的数据。使用Promise异步回调。<br/>-device:指定远程查询的设备networkId。<br/>-table:指定远程查询的表名。<br/>-predicates:表示RdbPredicates的实例对象,指定查询的条件。<br/>-columns:表示要查询的列。如果值为空,则查询应用于所有列。 |
74
75### 数据库谓词的使用
76
77关系型数据库提供了用于设置数据库操作条件的谓词RdbPredicates,该类确定RDB中条件表达式的值是true还是false。
78
79以下列举几个常用谓词,更多谓词的使用请见[关系型数据库谓词](../reference/apis/js-apis-data-relationalStore.md#rdbpredicates)。
80
81**表6** 数据库谓词API
82
83| 类名            | 接口名                                                       | 描述                                                         |
84| --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
85| RdbPredicates | equalTo(field: string, value: ValueType): RdbPredicates    | 配置谓词以匹配数据字段为ValueType且值等于指定值的字段。<br/>-field:数据库表中的列名。<br/>-value:指示要与谓词匹配的值。<br/>-RdbPredicates:返回与指定字段匹配的谓词。 |
86| RdbPredicates | notEqualTo(field: string, value: ValueType): RdbPredicates | 配置谓词以匹配数据字段为ValueType且值不等于指定值的字段。<br/>-field:数据库表中的列名。<br/>-value:指示要与谓词匹配的值。<br/>-RdbPredicates:返回与指定字段匹配的谓词。 |
87| RdbPredicates | or(): RdbPredicates                                        | 将或条件添加到谓词中。<br/>-RdbPredicates:返回带有或条件的谓词。 |
88| RdbPredicates | and(): RdbPredicates                                       | 向谓词添加和条件。<br/>-RdbPredicates:返回带有和条件的谓词。 |
89| RdbPredicates | contains(field: string, value: string): RdbPredicates      | 配置谓词以匹配数据字段为String且value包含指定值的字段。<br/>-field:数据库表中的列名。<br/>-value:指示要与谓词匹配的值。<br/>-RdbPredicates:返回带有包含条件的谓词。 |
90
91
92### 查询结果集的使用
93
94关系型数据库提供了查询返回的结果集ResultSet,其指向查询结果中的一行数据,供用户对查询结果进行遍历和访问。
95
96更多结果集的接口使用,请见[结果集](../reference/apis/js-apis-data-relationalStore.md#resultset)。
97
98> **须知:**
99> **结果集使用完后,请一定要调用close方法显式关闭。**
100
101**表7** 结果集API
102
103| 类名        | 接口名                                   | 描述                                       |
104| ----------- | ---------------------------------------- | ------------------------------------------ |
105| ResultSet | goToFirstRow(): boolean                  | 将结果集移动到第一行。                     |
106| ResultSet | getString(columnIndex: number): string   | 获取当前行指定列的值,以String类型返回。   |
107| ResultSet | getBlob(columnIndex: number): Uint8Array | 获取当前行指定列的值,以字节数组形式返回。 |
108| ResultSet | getDouble(columnIndex: number): number   | 获取当前行指定列的值,以double型返回。     |
109| ResultSet | getLong(columnIndex: number): number     | 获取当前行指定列的值,以Long形式返回。     |
110| ResultSet | close(): void                            | 关闭结果集。                               |
111
112
113
114### 设置分布式列表
115
116> **说明:**
117>
118> - 在使用RdbStore的setDistributedTables、obtainDistributedTableName、sync、on、off接口时,需要请求相应的权限:ohos.permission.DISTRIBUTED_DATASYNC119> - 使用分布式列表前,需要先建立设备间组网,具体接口及使用可见[设备管理](../reference/apis/js-apis-device-manager.md)。
120
121**设置分布式列表**
122
123**表8** 设置分布式列表
124
125| 类名       | 接口名                                                       | 描述                                                         |
126| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
127| RdbStore | setDistributedTables(tables: Array\<string>): Promise\<void> | 设置分布式列表,使用Promise异步回调。<br/>-tables:要设置的分布式列表表名。 |
128
129**根据本地表名获取指定远程设备的分布式表名**
130
131用户根据本地表名获取指定远程设备的分布式表名。在查询远程设备数据库时,需要使用分布式表名。
132
133**表9** 根据本地表名获取指定远程设备的分布式表名
134
135| 类名       | 接口名                                                       | 描述                                                         |
136| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
137| RdbStore | obtainDistributedTableName(device: string, table: string): Promise\<string> | 根据本地表名获取指定远程设备的分布式表名。在查询远程设备数据库时,需要使用分布式表名,使用Promise异步回调。<br/>-device:远程设备。<br/>-table:本地表名。 |
138
139**在设备之间同步数据**
140
141**表10** 在设备之间同步数据
142
143| 类名       | 接口名                                                       | 描述                                                         |
144| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
145| RdbStore | sync(mode: SyncMode, predicates: RdbPredicates): Promise\<Array\<[string, number]>> | 在设备之间同步数据,使用Promise异步回调。<br/>-mode:指同步模式。SYNC_MODE_PUSH 表示数据从本地设备推送到远程设备;SYNC_MODE_PULL 表示数据从远程设备拉至本地设备。<br/>-predicates:约束同步数据和设备。<br>-string:设备ID;number:每个设备同步状态,0表示成功,其他值表示失败。 |
146
147**注册数据库的观察者**
148
149**表11** 注册数据库的观察者
150
151| 类名       | 接口名                                                       | 描述                                                         |
152| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
153| RdbStore | on(event: 'dataChange', type: SubscribeType, observer: Callback\<Array\<string>>): void | 注册数据库的观察者。当分布式数据库中的数据发生更改时,将调用回调。<br/>-type:订阅类型;SUBSCRIBE_TYPE_REMOTE 订阅远程数据更改。<br/>-observer:指分布式数据库中数据更改事件的观察者。 |
154
155**从数据库中删除指定类型的指定观察者**
156
157**表12** 从数据库中删除指定类型的指定观察者
158
159| 类名       | 接口名                                                       | 描述                                                         |
160| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
161| RdbStore | off(event:'dataChange', type: SubscribeType, observer: Callback\<Array\<string>>): void; | 从数据库中删除指定类型的指定观察者,使用callback异步回调。<br/>-type:订阅类型;SUBSCRIBE_TYPE_REMOTE 订阅远程数据更改。<br/>-observer:指已注册的数据更改观察者。 |
162
163### 数据库的备份和恢复
164
165**备份**
166
167**表13** 备份数据库
168
169| 类名       | 接口名                                        | 描述                                                         |
170| ---------- | --------------------------------------------- | ------------------------------------------------------------ |
171| RdbStore | backup(destName: string): Promise&lt;void&gt; | 以指定名称备份数据库,使用Promise异步回调。<br/>-destName:指定数据库的备份文件名。 |
172
173**恢复**
174
175**表14** 恢复数据库
176
177| 类名       | 接口名                                        | 描述                                                         |
178| ---------- | --------------------------------------------- | ------------------------------------------------------------ |
179| RdbStore | restore(srcName: string): Promise&lt;void&gt; | 从指定的数据库备份文件恢复数据库,使用Promise异步回调。<br/>-srcName:指定数据库的备份文件名。 |
180
181### 事务
182
183**表15** 事务
184
185| 类名     | 接口名                  | 描述                              |
186| -------- | ----------------------- | --------------------------------- |
187| RdbStore | beginTransaction(): void | 在开始执行SQL语句之前,开始事务。 |
188| RdbStore | commit(): void           | 提交已执行的SQL语句。             |
189| RdbStore | rollBack(): void         | 回滚已经执行的SQL语句。           |
190
191## 开发步骤
192
1931. 创建数据库。
194
195   (1) 配置数据库相关信息,包括数据库的名称、存储模式、是否为只读模式等。
196
197   (2) 初始化数据库表结构和相关数据。
198
199   (3) 创建数据库。
200
201   FA模型示例:
202
203    ```js
204   import relationalStore from '@ohos.data.relationalStore'
205   import featureAbility from '@ohos.ability.featureAbility'
206
207   var store;
208
209   // 获取context
210   let context = featureAbility.getContext();
211
212   const STORE_CONFIG = {
213       name: "RdbTest.db",
214       securityLevel: relationalStore.SecurityLevel.S1
215   };
216
217   relationalStore.getRdbStore(context, STORE_CONFIG, function (err, rdbStore) {
218     store = rdbStore;
219     if (err) {
220       console.error(`Get RdbStore failed, err: ${err}`);
221       return;
222     }
223     console.info(`Get RdbStore successfully.`);
224   })
225    ```
226    Stage模型示例:
227     ```ts
228   import relationalStore from '@ohos.data.relationalStore'
229   import UIAbility from '@ohos.app.ability.UIAbility'
230
231   class EntryAbility extends UIAbility {
232       onWindowStageCreate(windowStage) {
233         var store;
234         const STORE_CONFIG = {
235           name: "RdbTest.db",
236           securityLevel: relationalStore.SecurityLevel.S1
237         };
238
239         relationalStore.getRdbStore(this.context, STORE_CONFIG, function (err, rdbStore) {
240           store = rdbStore;
241           if (err) {
242             console.error(`Get RdbStore failed, err: ${err}`);
243             return;
244           }
245           console.info(`Get RdbStore successfully.`);
246         })
247       }
248   }
249     ```
250
2512. 插入数据。
252
253   (1) 构造要插入的数据,以ValuesBucket形式存储。
254
255   (2) 调用关系型数据库提供的插入接口。
256
257   示例代码如下:
258
259    ```js
260    let u8 = new Uint8Array([1, 2, 3]);
261    const valueBucket = { "name": "Tom", "age": 18, "salary": 100.5, "blobType": u8 };
262    let insertPromise = store.insert("test", valueBucket);
263    ```
264
265    ```js
266    //使用事务插入数据
267    try {
268      store.beginTransaction();
269      let u8 = new Uint8Array([1, 2, 3]);
270      const valueBucket = { "name": "Tom", "age": 18, "salary": 100.5, "blobType": u8 };
271      let promise = store.insert("test", valueBucket);
272      promise.then(() => {
273        store.commit();
274      })
275    } catch (err) {
276      console.error(`Transaction failed, err: ${err}`);
277      store.rollBack();
278    }
279    ```
280
2813. 查询数据。
282
283   (1) 构造用于查询的谓词对象,设置查询条件。
284
285   (2) 调用查询接口查询数据。
286
287   (3) 调用结果集接口,返回查询结果。
288
289   示例代码如下:
290
291    ```js
292    let predicates = new relationalStore.RdbPredicates("test");
293    predicates.equalTo("name", "Tom");
294    let promisequery = store.query(predicates);
295    promisequery.then((resultSet) => {
296      resultSet.goToFirstRow();
297      const id = resultSet.getLong(resultSet.getColumnIndex("id"));
298      const name = resultSet.getString(resultSet.getColumnIndex("name"));
299      const age = resultSet.getLong(resultSet.getColumnIndex("age"));
300      const salary = resultSet.getDouble(resultSet.getColumnIndex("salary"));
301      const blobType = resultSet.getBlob(resultSet.getColumnIndex("blobType"));
302      resultSet.close();
303    })
304    ```
305
3064. 设置分布式同步表。
307
308    (1) 权限配置文件中增加以下配置。
309
310    ```json
311    "requestPermissions":
312    {
313      "name": "ohos.permission.DISTRIBUTED_DATASYNC"
314    }
315    ```
316
317    (2) 获取应用权限。
318
319    (3) 数据库调用接口设置分布式同步列表。
320
321    (4) 判断是否设置成功。
322
323   示例代码如下:
324
325    ```js
326    let context = featureAbility.getContext();
327    context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666, function (result) {
328      console.info(`result.requestCode=${result.requestCode}`);
329    })
330    let promise = store.setDistributedTables(["test"]);
331    promise.then(() => {
332      console.info(`setDistributedTables success.`);
333    }).catch((err) => {
334      console.error(`setDistributedTables failed, ${err}`);
335    })
336    ```
337
3385. 分布式数据同步。
339
340    (1) 构造用于同步分布式表的谓词对象,指定组网内的远程设备。
341
342    (2) 调用同步数据的接口。
343
344    (3) 判断数据同步是否成功。
345
346    示例代码如下:
347
348    ```js
349    let predicate = new relationalStore.RdbPredicates('test');
350    predicate.inDevices(['12345678abcde']);
351    let promise = store.sync(relationalStore.SyncMode.SYNC_MODE_PUSH, predicate);
352    promise.then((result) => {
353      console.info(`sync done.`);
354      for (let i = 0; i < result.length; i++) {
355        console.info(`device=${result[i][0]}, status=${result[i][1]}`);
356      }
357    }).catch((err) => {
358      console.error(`sync failed, err: ${err}`);
359    })
360    ```
361
3626. 分布式数据订阅。
363
364    (1) 调用分布式数据订阅接口,注册数据库的观察者。
365
366    (2) 当分布式数据库中的数据发生更改时,将调用回调。
367
368    示例代码如下:
369
370    ```js
371    function storeObserver(devices) {
372      for (let i = 0; i < devices.length; i++) {
373        console.info(`device= ${devices[i]} data changed`);
374      }
375    }
376
377    try {
378      store.on('dataChange', relationalStore.SubscribeType.SUBSCRIBE_TYPE_REMOTE, storeObserver);
379    } catch (err) {
380      console.error(`register observer failed, err: ${err}`);
381    }
382    ```
383
3847. 跨设备查询。
385
386    (1) 根据本地表名获取指定远程设备的分布式表名。
387
388    (2) 调用结果集接口,返回查询结果。
389
390    示例代码如下:
391
392    ```js
393   import deviceManager from '@ohos.distributedHardware.deviceManager'
394
395   let deviceIds = [];
396   deviceManager.createDeviceManager('bundleName', (err, value) => {
397     if (!err) {
398       let devManager = value;
399       if (devManager != null) {
400         // 获取deviceIds
401         let devices = devManager.getTrustedDeviceListSync();
402         for (let i = 0; i < devices.length; i++) {
403           deviceIds[i] = devices[i].deviceId;
404         }
405       }
406     }
407   })
408
409   let tableName = store.obtainDistributedTableName(deviceIds[0], "test");
410   let resultSet = store.querySql("SELECT * FROM " + tableName);
411    ```
412
4138. 远程查询。
414
415   (1) 构造用于查询分布式表的谓词对象,指定组网内的远程分布式表名和设备。
416
417   (2) 调用结果集接口,返回查询结果。
418
419   示例代码如下:
420
421   ```js
422    let rdbPredicate = new relationalStore.RdbPredicates('employee');
423    predicates.greaterThan("id", 0) ;
424    let promiseQuery = store.remoteQuery('12345678abcde', 'employee', rdbPredicate);
425    promiseQuery.then((resultSet) => {
426      while (resultSet.goToNextRow()) {
427        let idx = resultSet.getLong(0);
428        let name = resultSet.getString(1);
429        let age = resultSet.getLong(2);
430        console.info(`indx: ${idx}, name: ${name}, age: ${age}`);
431      }
432      resultSet.close();
433    }).catch((err) => {
434      console.error(`failed to remoteQuery, err: ${err}`);
435    })
436   ```
437
4389. 数据库的备份和恢复。
439
440   (1) 调用数据库的备份接口,备份当前数据库文件。
441
442   示例代码如下:
443
444   ```js
445    let promiseBackup = store.backup("dbBackup.db");
446    promiseBackup.then(() => {
447      console.info(`Backup success.`);
448    }).catch((err) => {
449      console.error(`Backup failed, err: ${err}`);
450    })
451   ```
452
453   (2) 调用数据库的恢复接口,从数据库的备份文件恢复数据库文件。
454
455   示例代码如下:
456
457   ```js
458    let promiseRestore = store.restore("dbBackup.db");
459    promiseRestore.then(() => {
460      console.info(`Restore success.`);
461    }).catch((err) => {
462      console.error(`Restore failed, err: ${err}`);
463    })
464   ```
465
466## 相关实例
467针对关系型数据库开发,有以下相关实例可供参考:
468
469- [`DistributedRdb`:分布式关系型数据库(ArkTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/data/DistributedRdb)
470
471- [关系型数据库(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/Data/JSRelationshipData)
472
473- [关系型数据库(ArkS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Data/Rdb)