HarmonyOS 应用开发之关系型数据库跨设备数据同步

场景介绍

当应用程序本地存储的关系型数据存在跨设备同步的需求时,可以将需要同步的表数据迁移到新的支持跨设备的表中,当然也可以在刚完成表创建时设置其支持跨设备。

基本概念

关系型数据库跨设备数据同步,支持应用在多设备间同步存储的关系型数据。

  • 分布式列表,应用在数据库中新创建表后,可以设置其为分布式表。在查询远程设备数据库时,根据本地表名可以获取指定远程设备的分布式表名。

  • 设备之间同步数据,数据同步有两种方式,将数据从本地设备推送到远程设备或将数据从远程设备拉至本地设备。

运作机制

底层通信组件完成设备发现和认证,会通知上层应用程序设备上线。收到设备上线的消息后数据管理服务可以在两个设备之间建立加密的数据传输通道,利用该通道在两个设备之间进行数据同步。

数据跨设备同步机制

业务将数据写入关系型数据库后,向数据管理服务发起同步请求。

数据管理服务从应用沙箱内读取待同步数据,根据对端设备的deviceId将数据发送到其他设备的数据管理服务。再由数据管理服务将数据写入同应用的数据库内。

数据变化通知机制

增、删、改数据库时,会给订阅者发送数据变化的通知。主要分为本地数据变化通知和分布式数据变化通知。

  • 本地数据变化通知:本地设备的应用内订阅数据变化通知,数据库增删改数据时,会收到通知。

  • 分布式数据变化通知:同一应用订阅组网内其他设备数据变化的通知,其他设备增删改数据时,本设备会收到通知。

约束限制

  • 每个应用程序最多支持同时打开16个关系型分布式数据库。

  • 单个数据库最多支持注册8个订阅数据变化的回调。

接口说明

以下是关系型设备协同分布式数据库跨设备数据同步功能的相关接口,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下表均以callback形式为例。

接口名称 描述
setDistributedTables(tables: Array<string>, callback: AsyncCallback<void>): void 设置分布式同步表。
sync(mode: SyncMode, predicates: RdbPredicates, callback: AsyncCallback<Array<string, number>>): void 分布式数据同步。
on(event: 'dataChange', type: SubscribeType, observer: Callback<Array<string>>): void 订阅分布式数据变化。
off(event:'dataChange', type: SubscribeType, observer: Callback<Array<string>>): void 取消订阅分布式数据变化。
obtainDistributedTableName(device: string, table: string, callback: AsyncCallback<string>): void; 根据本地数据库表名获取指定设备上的表名。
remoteQuery(device: string, table: string, predicates: RdbPredicates, columns: Array<string> , callback: AsyncCallback<ResultSet>): void 根据指定条件查询远程设备数据库中的数据。

开发步骤

说明:

数据只允许向数据安全标签不高于对端设备安全等级的设备同步数据,具体规则可见跨设备同步访问控制机制。

  1. 导入模块。
ts 复制代码
   import relationalStore from '@ohos.data.relationalStore';
  1. 请求权限。

    1. 需要申请ohos.permission.DISTRIBUTED_DATASYNC权限。
    2. 同时需要在应用首次启动时弹窗向用户申请授权。
  2. 创建关系型数据库,设置将需要进行分布式同步的表。

    ts 复制代码
    import UIAbility from '@ohos.app.ability.UIAbility';
    import window from '@ohos.window';
    import { BusinessError } from "@ohos.base";
    
    class EntryAbility extends UIAbility {
      onWindowStageCreate(windowStage: window.WindowStage) {
        const STORE_CONFIG: relationalStore.StoreConfig = {
          name: "RdbTest.db",
          securityLevel: relationalStore.SecurityLevel.S1
        };
           
        relationalStore.getRdbStore(this.context, STORE_CONFIG, (err: BusinessError, store: relationalStore.RdbStore) => {
          store.executeSql('CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INTEGER, SALARY REAL, CODES BLOB)', (err) => {
            // 设置分布式同步表。
            store.setDistributedTables(['EMPLOYEE']);
            // 进行数据的相关操作
          })
        })
      }
    }
  3. 分布式数据同步。使用SYNC_MODE_PUSH触发同步后,数据将从本设备向组网内的其它所有设备同步。

    ts 复制代码
    // 构造用于同步分布式表的谓词对象
    let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
    // 调用同步数据的接口
    if(store != undefined)
    {
      (store as relationalStore.RdbStore).sync(relationalStore.SyncMode.SYNC_MODE_PUSH, predicates, (err, result) => {
        // 判断数据同步是否成功
        if (err) {
          console.error(`Failed to sync data. Code:${err.code},message:${err.message}`);
          return;
        }
        console.info('Succeeded in syncing data.');
        for (let i = 0; i < result.length; i++) {
          console.info(`device:${result[i][0]},status:${result[i][1]}`);
        }
      })
    }
  4. 分布式数据订阅。数据同步变化将触发订阅回调方法执行,回调方法的入参为发生变化的设备ID。

    ts 复制代码
    let devices: string | undefined = undefined;
    try {
      // 调用分布式数据订阅接口,注册数据库的观察者
      // 当分布式数据库中的数据发生更改时,将调用回调
      if(store != undefined) {
        (store as relationalStore.RdbStore).on('dataChange', relationalStore.SubscribeType.SUBSCRIBE_TYPE_REMOTE, (storeObserver)=>{
          if(devices != undefined){
            for (let i = 0; i < devices.length; i++) {
              console.info(`The data of device:${devices[i]} has been changed.`);
            }
          }
        });
      }
    } catch (err) {
      console.error('Failed to register observer. Code:${err.code},message:${err.message}');
    }
    // 当前不需要订阅数据变化时,可以将其取消。
    try {
      if(store != undefined) {
        (store as relationalStore.RdbStore).off('dataChange', relationalStore.SubscribeType.SUBSCRIBE_TYPE_REMOTE, (storeObserver)=>{
        });
      }
    } catch (err) {
      console.error('Failed to register observer. Code:${err.code},message:${err.message}');
    }
  5. 跨设备查询。如果数据未完成同步,或未触发数据同步,应用可以使用此接口从指定的设备上查询数据。

说明:

deviceIds通过调用deviceManager.getAvailableDeviceListSync方法得到。

ts 复制代码
// 获取deviceIds
import deviceManager from '@ohos.distributedDeviceManager';
import { BusinessError } from '@ohos.base'

let dmInstance: deviceManager.DeviceManager;
let deviceId: string | undefined = undefined ;

try {
  dmInstance = deviceManager.createDeviceManager("com.example.appdatamgrverify");
  let devices = dmInstance.getAvailableDeviceListSync();

  deviceId = devices[0].networkId;

  // 构造用于查询分布式表的谓词对象
  let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
  // 调用跨设备查询接口,并返回查询结果
  if(store != undefined && deviceId != undefined) {
    (store as relationalStore.RdbStore).remoteQuery(deviceId, 'EMPLOYEE', predicates, ['ID', 'NAME', 'AGE', 'SALARY', 'CODES'],
      (err: BusinessError, resultSet: relationalStore.ResultSet) => {
        if (err) {
          console.error(`Failed to remoteQuery data. Code:${err.code},message:${err.message}`);
          return;
        }
        console.info(`ResultSet column names: ${resultSet.columnNames}, column count: ${resultSet.columnCount}`);
      }
    )
  }
} catch (err) {
  let code = (err as BusinessError).code;
  let message = (err as BusinessError).message;
  console.error("createDeviceManager errCode:" + code + ",errMessage:" + message);
}

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ......

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ......

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ......

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题

2.性能优化方向

3.架构方向

4.鸿蒙开发系统底层方向

5.鸿蒙音视频开发方向

6.鸿蒙车载开发方向

7.鸿蒙南向开发方向

相关推荐
行者-全栈开发30 分钟前
【鸿蒙心迹】多线程并发实战——TaskPool 与 Worker 选型与踩坑(HarmonyOS 7.x)
华为·harmonyos·多线程并发·worker·taskpool·线程通信·harmonyos 并发
星恒随风42 分钟前
MySQL 从零入门(六):复合查询详解——多表查询、自连接、子查询与 UNION
linux·服务器·数据库·mysql
无奈笑天下2 小时前
银河麒麟上lsblk命令教程详解
linux·运维·服务器·数据库
OH_TPC3 小时前
@ohos/aki 源码解读(一):一行绑定背后,宏、模板与索引分发
harmonyos
xiaoye-duck3 小时前
《C++ 项目:手写大模型接入 SDK》会话模块整合:内存 SessionManager 与 DataManager 持久化联动
开发语言·数据库·c++·语言模型
贾伟康3 小时前
【解压时刻|13】HarmonyOS ArkTS 启动链路审计:从 EntryAbility、AppStore 到 Navigation 首屏
harmonyos·arkts·appstorage·应用启动·entryability
AllData公司负责人4 小时前
AI大模型数据开发底座系列说明书:AllData集成DB-GPT开源项目建设 AI 多模态分析底座,涵盖模态解析/智能大屏/MCP 扩展!
大数据·数据库·人工智能·gpt·数据采集·数据接入·模态解析
贾伟康4 小时前
【古诗词闯关|12】HarmonyOS ArkTS 单页组件拆分实战:降低题库、闯关与结果弹层耦合
harmonyos·arkts·状态管理·arkui·组件化
2601_967987374 小时前
Sqlite参考手册
数据库·python·sqlite·api·教程
隔窗听雨眠5 小时前
Oracle日志体系分层结构与故障定位路径
数据库·oracle·故障排查