HarmonyOS Developer 开发指导
分布式数据服务概述
分布式数据服务(Distributed Data Service,DDS)为应用程序提供不同设备间数据库的分布式协同能力。
通过调用分布式数据接口,应用程序将数据保存到分布式数据库中。通过结合帐号、应用和数据库三元组,分布式数据服务对属于不同应用的数据进行隔离,保证不同应用之间的数据不能通过分布式数据服务互相访问。在通过可信认证的设备间,分布式数据服务支持应用数据相互同步,为用户提供在多种终端设备上最终一致的数据访问体验。
关于数据库锁机制,开发者无需关注其具体实现。
基本概念
KV数据模型
“KV数据模型”是“Key-Value数据模型”的简称,“Key-Value”即“键-值”;其数据以键值对的形式进行组织、索引和存储。
KV数据模型适合不涉及过多数据关系和业务关系的业务数据存储,比SQL数据库存储拥有更好的读写性能,同时因其在分布式场景中降低了解决数据库版本兼容问题的复杂度,和数据同步过程中冲突解决的复杂度而被广泛使用。分布式数据库也是基于KV数据模型,对外提供KV类型的访问接口。
分布式数据库事务性
分布式数据库事务支持本地事务(和传统数据库的事务概念一致)和同步事务。同步事务是指在设备之间同步数据时,以本地事务为单位进行同步,一次本地事务的修改要么都同步成功,要么都同步失败。
分布式数据库一致性
在分布式场景中一般会涉及多个设备,组网内设备之间看到的数据是否一致称为分布式数据库的一致性。分布式数据库一致性可以分为强一致性、弱一致性和最终一致性。
- 强一致性:是指某一设备成功增、删、改数据后,组网内设备对该数据的读取操作都将得到更新后的值。
- 弱一致性:是指某一设备成功增、删、改数据后,组网内设备可能读取到本次更新数据,也可能读取不到,不能保证在多长时间后每个设备的数据一定是一致的。
- 最终一致性:是指某一设备成功增、删、改数据后,组网内设备可能读取不到本次更新数据,但在某个时间窗口之后组网内设备的数据能够达到一致状态。
强一致性对分布式数据的管理要求非常高,在服务器的分布式场景可能会遇到。因为移动终端设备的不常在线、以及无中心的特性,分布式数据服务不支持强一致性,只支持最终一致性。
分布式数据库同步
底层通信组件完成设备发现和认证,会通知上层应用程序(包括分布式数据服务)设备上线。收到设备上线的消息后分布式数据服务可以在两个设备之间建立加密的数据传输通道,利用该通道在两个设备之间进行数据同步。
分布式数据服务提供了两种同步方式:手动同步和自动同步。
- 手动同步:由应用程序调用sync接口来触发,需要指定同步的设备列表和同步模式。同步模式分为PULL_ONLY(将远端数据拉到本端)、PUSH_ONLY(将本端数据推送到远端)和PUSH_PULL(将本端数据推送到远端同时也将远端数据拉取到本端)。内部接口支持按条件过滤同步,将符合条件的数据同步到远端。
- 自动同步:包括全量同步和按条件订阅同步。全量同步由分布式数据库自动将本端数据推送到远端,同时也将远端数据拉取到本端来完成数据同步,同步时机包括设备上线、应用程序更新数据等,应用不需要主动调用sync接口;内部接口支持按条件订阅同步,将远端符合订阅条件的数据自动同步到本端。
单版本分布式数据库
单版本分布式数据库是指数据在本地保存是以单个KV条目为单位的方式保存,对每个Key最多只保存一个条目项,当数据在本地被用户修改时,不管它是否已经被同步出去,均直接在这个条目上进行修改。同步也以此为基础,按照它在本地被写入或更改的顺序将当前最新一次修改逐条同步至远端设备。
设备协同分布式数据库
设备协同分布式数据库建立在单版本分布式数据库之上,对应用程序存入的KV数据中的Key前面拼接了本设备的DeviceID标识符,这样能保证每个设备产生的数据严格隔离,底层按照设备的维度管理这些数据,设备协同分布式数据库支持以设备的维度查询分布式数据,但是不支持修改远端设备同步过来的数据。
分布式数据库冲突解决策略
分布式数据库多设备提交冲突场景,在给提交冲突做合并的过程中,如果多个设备同时修改了同一数据,则称这种场景为数据冲突。数据冲突采用默认冲突解决策略(Last-write-wins),基于提交时间戳,取时间戳较大的提交数据,当前不支持定制冲突解决策略。
数据库Schema化管理与谓词查询
单版本数据库支持在创建和打开数据库时指定Schema,数据库根据Schema定义感知KV记录的Value格式,以实现对Value值结构的检查,并基于Value中的字段实现索引建立和谓词查询。
分布式数据库备份能力
提供分布式数据库备份能力,业务通过设置backup属性为true,可以触发分布式数据服务每日备份。当分布式数据库发生损坏,分布式数据服务会删除损坏数据库,并且从备份数据库中恢复上次备份的数据。如果不存在备份数据库,则创建一个新的数据库。同时支持加密数据库的备份能力。
运作机制
分布式数据服务支撑HarmonyOS系统上应用程序数据库数据分布式管理,支持数据在相同帐号的多端设备之间相互同步,为用户在多端设备上提供一致的用户体验,分布式数据服务包含五部分:
- 服务接口:分布式数据服务提供专门的数据库创建、数据访问、数据订阅等接口给应用程序调用,接口支持KV数据模型,支持常用的数据类型,同时确保接口的兼容性、易用性和可发布性。
- 服务组件:服务组件负责服务内元数据管理、权限管理、加密管理、备份和恢复管理以及多用户管理等、同时负责初始化底层分布式DB的存储组件、同步组件和通信适配层。
- 存储组件:存储组件负责数据的访问、数据的缩减、事务、快照、数据库加密,以及数据合并和冲突解决等特性。
- 同步组件:同步组件连结了存储组件与通信组件,其目标是保持在线设备间的数据库数据一致性,包括将本地产生的未同步数据同步给其他设备,接收来自其他设备发送过来的数据,并合并到本地设备中。
- 通信适配层:通信适配层负责调用底层公共通信层的接口完成通信管道的创建、连接,接收设备上下线消息,维护已连接和断开设备列表的元数据,同时将设备上下线信息发送给上层同步组件,同步组件维护连接的设备列表,同步数据时根据该列表,调用通信适配层的接口将数据封装并发送给连接的设备。
应用程序通过调用分布式数据服务接口实现分布式数据库创建、访问、订阅功能,服务接口通过操作服务组件提供的能力,将数据存储至存储组件,存储组件调用同步组件实现将数据同步,同步组件使用通信适配层将数据同步至远端设备,远端设备通过同步组件接收数据,并更新至本端存储组件,通过服务接口提供给应用程序使用。
图1 数据分布式运作示意图
约束与限制
- 分布式数据服务的数据模型仅支持KV数据模型,不支持外键、触发器等关系型数据库中的功能。
- 分布式数据服务支持的KV数据模型规格:
○ 设备协同数据库,针对每条记录,Key的长度≤896 Byte,Value的长度<4 MB。
○ 单版本数据库,针对每条记录,Key的长度≤1 KB,Value的长度<4 MB。
○ 每个应用程序最多支持同时打开16个分布式数据库。
- 分布式数据库与本地数据库的使用场景不同,因此开发者应识别需要在设备间进行同步的数据,并将这些数据保存到分布式数据库中。
- 分布式数据服务当前不支持应用程序自定义冲突解决策略。
- 分布式数据服务针对每个应用程序当前的流控机制:KvStore的接口1秒最大访问1000次,1分钟最大访问10000次;KvManager的接口1秒最大访问50次,1分钟最大访问500次。
- 分布式数据库事件回调方法中不允许进行阻塞操作,例如修改UI组件。
分布式数据服务开发指导
场景介绍
分布式数据服务主要实现用户设备中应用程序数据内容的分布式同步。当设备1上的应用A在分布式数据库中增、删、改数据后,设备2上的应用A也可以获取到该数据库变化。可在分布式图库、信息、通讯录、文件管理器等场景中使用。
接口说明
分布式数据相关功能接口请见分布式数据管理。
表1 分布式数据服务关键API功能介绍
接口名称 | 描述 |
createKVManager(config: KVManagerConfig, callback: AsyncCallback<KVManager>): void createKVManager(config: KVManagerConfig): Promise<KVManager> | 创建一个KVManager对象实例,用于管理数据库对象。 |
getKVStore<T extends KVStore>(storeId: string, options: Options, callback: AsyncCallback<T>): void getKVStore<T extends KVStore>(storeId: string, options: Options): Promise<T> | 指定Options和storeId,创建并获取指定类型KVStore数据库。 |
put(key: string, value: Uint8Array|string|number|boolean, callback: AsyncCallback<void>): void put(key: string, value: Uint8Array|string|number|boolean): Promise<void> | 插入和更新数据。 |
delete(key: string, callback: AsyncCallback<void>): void delete(key: string): Promise<void> | 删除数据。 |
get(key: string, callback: AsyncCallback<Uint8Array|string|boolean|number>): void get(key: string): Promise<Uint8Array|string|boolean|number> | 查询数据。 |
on(event: 'dataChange', type: SubscribeType, observer: Callback<ChangeNotification>): void on(event: 'syncComplete', syncCallback: Callback<Array<[string,number]>>): void | 订阅数据库中数据的变化。 |
开发步骤
以单版本分布式数据库为例,说明开发步骤。
- 导入模块。
import distributedData from '@ohos.data.distributedData';
- 根据配置构造分布式数据库管理类实例。
a. 根据应用上下文创建kvManagerConfig对象。
b. 创建分布式数据库管理器实例。
以下为创建分布式数据库管理器的代码示例:
let kvManager;
try {
const kvManagerConfig = {
bundleName : 'com.example.datamanagertest',
userInfo : {
userId : '0',
userType : distributedData.UserType.SAME_USER_ID
}
}
distributedData.createKVManager(kvManagerConfig, function (err, manager) {
if (err) {
console.log("Failed to create KVManager: " + JSON.stringify(err));
return;
}
console.log("Succeeded in creating KVManager");
kvManager = manager;
});
} catch (e) {
console.log("An unexpected error occurred. Error:" + e);
}
- 获取/创建分布式数据库。
a. 声明需要创建的分布式数据库ID描述。
b. 创建分布式数据库。
以下为创建分布式数据库的代码示例:
let kvStore;
try {
const options = {
createIfMissing: true,
encrypt: false,
backup: false,
autoSync: false,
kvStoreType: distributedData.KVStoreType.SINGLE_VERSION,
securityLevel: distributedData.SecurityLevel.S1
};
kvManager.getKVStore('storeId', options, function (err, store) {
if (err) {
console.error(`Failed to get KVStore: code is ${err.code},message is ${err.message}`);
return;
}
console.log('Succeeded in getting KVStore');
kvStore = store;
});
} catch (e) {
console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`);
}
- 订阅分布式数据变化。
以下为订阅单版本分布式数据库数据变化通知的代码示例:
try{
kvStore.on('dataChange', distributedData.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}`);
}
- 将数据写入分布式数据库。
a. 构造需要写入分布式数据库的Key(键)和Value(值)。
b. 将键值数据写入分布式数据库。
以下为将字符串类型键值数据写入分布式数据库的代码示例:
const KEY_TEST_STRING_ELEMENT = 'key_test_string';
const VALUE_TEST_STRING_ELEMENT = 'value-test-string';
try {
kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) {
if (err != undefined) {
console.error(`Failed to put.code is ${err.code},message is ${err.message}`);
return;
}
console.log("Succeeded in putting");
});
}catch (e) {
console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`);
}
- 查询分布式数据库数据。
a. 构造需要从单版本分布式数据库中查询的Key(键)。
b. 从单版本分布式数据库中获取数据。
以下为从分布式数据库中查询字符串类型数据的代码示例:
const KEY_TEST_STRING_ELEMENT = 'key_test_string';
const VALUE_TEST_STRING_ELEMENT = 'value-test-string';
try {
kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) {
if (err != undefined) {
console.error(`Failed to put.code is ${err.code},message is ${err.message}`);
return;
}
console.log("Succeeded in putting");
kvStore.get(KEY_TEST_STRING_ELEMENT, function (err,data) {
if (err != undefined) {
console.error(`Failed to get.code is ${err.code},message is ${err.message}`);
return;
}
console.log(`Succeeded in getting data:${data}`);
});
});
}catch (e) {
console.error(`Failed to get.code is ${e.code},message is ${e.message}`);
}
关系型数据库概述
关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。当应用卸载后,其相关数据库会被自动清除。
关于数据库锁机制,开发者无需关注其具体实现。
基本概念
- 关系型数据库
基于关系模型来管理数据的数据库,以行和列的形式存储数据。 - 谓词
数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。 - 结果集
指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便的拿到用户想要的数据。 - SQLite数据库
一款遵守ACID的轻型开源关系型数据库管理系统。
运作机制
关系型数据库对外提供通用的操作接口,底层使用SQLite作为持久化存储引擎,支持SQLite具有的所有数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。
图1 关系型数据库运作机制
默认配置
- 系统默认日志方式是WAL(Write Ahead Log)模式。
- 系统默认落盘方式是FULL模式。
- HarmonyOS数据库使用的共享内存默认大小是2MB。
约束与限制
- 数据库中连接池的最大数量是4个,用以管理用户的读操作。
- 为保证数据的准确性,数据库同一时间只能支持一个写操作。
关系型数据库开发指导
场景介绍
关系型数据库是在SQLite基础上实现的本地数据操作机制,提供给用户无需编写原生SQL语句就能进行数据增删改查的方法,同时也支持原生SQL语句操作。
接口说明
以下是关系型数据库的常用接口说明,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下表均以Promise形式为例,更多接口及使用方式请见关系型数据库。
数据库的创建和删除
关系型数据库提供了数据库创建方式,以及对应的删除接口,涉及的API如下所示。
表1 数据库创建和删除API
接口名 | 描述 |
getRdbStore(context: Context, config: StoreConfig, version: number): Promise<RdbStore> | 获得一个相关的RdbStore,操作关系型数据库,用户可以根据自己的需求配置RdbStore的参数,然后通过RdbStore调用相关接口可以执行相关的数据操作,使用Promise异步回调。 -context:应用程序或功能的上下文。 -config:与此RDB存储相关的数据库配置。 -version:数据库版本。目前暂不支持通过version自动识别数据库升级降级操作,只能由开发者自行维护。 |
deleteRdbStore(context: Context, name: string): Promise<void> | 使用指定的数据库文件配置删除数据库,使用Promise异步回调。 -context:应用程序或功能的上下文。 -name:数据库名称。 |
数据库的增删改查
关系型数据库提供对本地数据增删改查操作的能力,相关API如下所示。
- 新增
关系型数据库提供了插入数据的接口,通过ValuesBucket输入要存储的数据,通过返回值判断是否插入成功,插入成功时返回最新插入数据所在的行号,失败时则返回-1。
表2数据库插入API
类名 | 接口名 | 描述 |
RdbStore | insert(table: string, values: ValuesBucket): Promise<number> | 向目标表中插入一行数据,使用Promise异步回调。 如果操作成功,返回行ID;否则返回-1。 -table:指定的目标表名。 -values:表示要插入到表中的数据行。 |
- 更新
调用更新接口,传入要更新的数据,并通过RdbPredicates指定更新条件。该接口的返回值表示更新操作影响的行数。如果更新失败,则返回0。
表3数据库更新API
类名 | 接口名 | 描述 |
RdbStore | update(values: ValuesBucket, predicates: RdbPredicates): Promise<number> | 根据RdbPredicates的指定实例对象更新数据库中的数据,使用Promise异步回调。 返回受影响的行数。 -values:以ValuesBucket存储的要更新的数据。 -predicates:表示RdbPredicates的实例对象指定的更新条件。 |
- 删除
调用删除接口,通过RdbPredicates指定删除条件。该接口的返回值表示删除的数据行数,可根据此值判断是否删除成功。如果删除失败,则返回0。
表4数据库删除API
类名 | 接口名 | 描述 |
RdbStore | delete(predicates: RdbPredicates): Promise<number> | 根据RdbPredicates的指定实例对象从数据库中删除数据,使用Promise异步回调。 返回受影响的行数。 -predicates:RdbPredicates的实例对象指定的删除条件。 |
- 查询
关系型数据库提供了两种查询数据的方式:
○ 直接调用查询接口。使用该接口,会将包含查询条件的谓词自动拼接成完整的SQL语句进行查询操作,无需用户传入原生的SQL语句。
○ 执行原生的SQL语句进行查询操作。
表5 数据库查询API
类名 | 接口名 | 描述 |
RdbStore | query(predicates: RdbPredicates, columns?: Array<string>): Promise<ResultSet> | 根据指定条件查询数据库中的数据,使用Promise异步回调。 -predicates:表示RdbPredicates的实例对象指定的查询条件。 -columns:表示要查询的列。如果值为空,则查询应用于所有列。 |
RdbStore | querySql(sql: string, bindArgs?: Array<ValueType>): Promise<ResultSet> | 根据指定SQL语句查询数据库中的数据,使用Promise异步回调。 -sql:指定要查询的SQL语句。 -bindArgs:SQL语句中参数的值。 |
数据库谓词的使用
关系型数据库提供了用于设置数据库操作条件的谓词RdbPredicates,该类确定RDB中条件表达式的值是true还是false。
以下列举几个常用谓词,更多谓词的使用请见关系数据库谓词。
表6 数据库谓词API
类名 | 接口名 | 描述 |
RdbPredicates | equalTo(field: string, value: ValueType): RdbPredicates | 配置谓词以匹配数据字段为ValueType且值等于指定值的字段。 -field:数据库表中的列名。 -value:指示要与谓词匹配的值。 -RdbPredicates:返回与指定字段匹配的谓词。 |
RdbPredicates | notEqualTo(field: string, value: ValueType): RdbPredicates | 配置谓词以匹配数据字段为ValueType且值不等于指定值的字段。 -field:数据库表中的列名。 -value:指示要与谓词匹配的值。 -RdbPredicates:返回与指定字段匹配的谓词。 |
RdbPredicates | or(): RdbPredicates | 将或条件添加到谓词中。 -RdbPredicates:返回带有或条件的谓词。 |
RdbPredicates | and(): RdbPredicates | 向谓词添加和条件。 -RdbPredicates:返回带有和条件的谓词。 |
RdbPredicates | contains(field: string, value: string): RdbPredicates | 配置谓词以匹配数据字段为String且value包含指定值的字段。 -field:数据库表中的列名。 -value:指示要与谓词匹配的值。 -RdbPredicates:返回带有包含条件的谓词。 |
查询结果集的使用
关系型数据库提供了查询返回的结果集ResultSet,其指向查询结果中的一行数据,供用户对查询结果进行遍历和访问。
更多结果集的接口使用,请见结果集。
注意
结果集使用完后,请一定要调用close方法显式关闭。
表7 结果集API
类名 | 接口名 | 描述 |
ResultSet | goToFirstRow(): boolean | 将结果集移动到第一行。 |
ResultSet | getString(columnIndex: number): string | 获取当前行指定列的值,以String类型返回。 |
ResultSet | getBlob(columnIndex: number): Uint8Array | 获取当前行指定列的值,以字节数组形式返回。 |
ResultSet | getDouble(columnIndex: number): number | 获取当前行指定列的值,以double型返回。 |
ResultSet | getLong(columnIndex: number): number | 获取当前行指定列的值,以Long形式返回。 |
ResultSet | close(): void | 关闭结果集。 |
设置分布式列表
说明
在使用RdbStore的setDistributedTables、obtainDistributedTableName、sync、on、off接口时,需要请求相应的权限:ohos.permission.DISTRIBUTED_DATASYNC。
设置分布式列表
表8 设置分布式列表
类名 | 接口名 | 描述 |
RdbStore | setDistributedTables(tables: Array<string>): Promise<void> | 设置分布式列表,使用Promise异步回调。 -tables:要设置的分布式列表表名。 |
根据本地表名获取指定远程设备的分布式表名
用户根据本地表名获取指定远程设备的分布式表名。在查询远程设备数据库时,需要使用分布式表名。
表9 根据本地表名获取指定远程设备的分布式表名
类名 | 接口名 | 描述 |
RdbStore | obtainDistributedTableName(device: string, table: string): Promise<string> | 根据本地表名获取指定远程设备的分布式表名。在查询远程设备数据库时,需要使用分布式表名,使用Promise异步回调。 -device:远程设备。 -table:本地表名。 |
在设备之间同步数据
表10 在设备之间同步数据
类名 | 接口名 | 描述 |
RdbStore | sync(mode: SyncMode, predicates: RdbPredicates): Promise<Array<[string, number]>> | 在设备之间同步数据,使用Promise异步回调。 -mode:指同步模式。SYNC_MODE_PUSH 表示数据从本地设备推送到远程设备;SYNC_MODE_PULL 表示数据从远程设备拉至本地设备。 -predicates:约束同步数据和设备。 -string:设备ID;number:每个设备同步状态,0表示成功,其他值表示失败。 |
注册数据库的观察者
表11 注册数据库的观察者
类名 | 接口名 | 描述 |
RdbStore | on(event: 'dataChange', type: SubscribeType, observer: Callback<Array<string>>): void | 注册数据库的观察者。当分布式数据库中的数据发生更改时,将调用回调。 -type:订阅类型;SUBSCRIBE_TYPE_REMOTE 订阅远程数据更改。 -observer:指分布式数据库中数据更改事件的观察者。 |
从数据库中删除指定类型的指定观察者
表12 从数据库中删除指定类型的指定观察者
类名 | 接口名 | 描述 |
RdbStore | off(event:'dataChange', type: SubscribeType, observer: Callback<Array<string>>): void; | 从数据库中删除指定类型的指定观察者,使用callback异步回调。 -type:订阅类型;SUBSCRIBE_TYPE_REMOTE 订阅远程数据更改。 -observer:指已注册的数据更改观察者。 |
事务
表1 事务
类名 | 接口名 | 描述 |
RdbStore | beginTransaction(): void | 在开始执行SQL语句之前,开始事务。 |
RdbStore | commit(): void | 提交已执行的SQL语句。 |
RdbStore | rollBack(): void | 回滚已经执行的SQL语句。 |
开发步骤
- 创建数据库。
(1) 配置数据库相关信息,包括数据库的名称、存储模式、是否为只读模式等。
(2) 初始化数据库表结构和相关数据。
(3) 创建数据库。
FA模型示例:
import data_rdb from '@ohos.data.rdb'
// 获取context
import featureAbility from '@ohos.ability.featureAbility'
let context = featureAbility.getContext()
const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)";
const STORE_CONFIG = { name: "RdbTest.db" }
data_rdb.getRdbStore(context, STORE_CONFIG, 1, function (err, rdbStore) {
rdbStore.executeSql(CREATE_TABLE_TEST)
console.info('create table done.')
})
Stage模型示例:
import data_rdb from '@ohos.data.rdb'
// 获取context
import UIAbility from '@ohos.app.ability.UIAbility'
let context = null
class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage) {
context = this.context
}
}
const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)";
const STORE_CONFIG = { name: "rdbstore.db" }
data_rdb.getRdbStore(context, STORE_CONFIG, 1, function (err, rdbStore) {
rdbStore.executeSql(CREATE_TABLE_TEST)
console.info('create table done.')
})
- 插入数据。
(1) 构造要插入的数据,以ValuesBucket形式存储。
(2) 调用关系型数据库提供的插入接口。
示例代码如下:
var u8 = new Uint8Array([1, 2, 3])
const valueBucket = { "name": "Tom", "age": 18, "salary": 100.5, "blobType": u8 }
let insertPromise = rdbStore.insert("test", valueBucket)
- 查询数据。
(1) 构造用于查询的谓词对象,设置查询条件。
(2) 调用查询接口查询数据。
(3) 调用结果集接口,返回查询结果。
示例代码如下:
let predicates = new data_rdb.RdbPredicates("test");
predicates.equalTo("name", "Tom")
let promisequery = rdbStore.query(predicates)
promisequery.then((resultSet) => {
resultSet.goToFirstRow()
const id = resultSet.getLong(resultSet.getColumnIndex("id"))
const name = resultSet.getString(resultSet.getColumnIndex("name"))
const age = resultSet.getLong(resultSet.getColumnIndex("age"))
const salary = resultSet.getDouble(resultSet.getColumnIndex("salary"))
const blobType = resultSet.getBlob(resultSet.getColumnIndex("blobType"))
resultSet.close()
})
- 设置分布式同步表。
(1) 权限配置文件中增加以下配置。
"requestPermissions":
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC"
}
(2) 获取应用权限。
(3) 数据库调用接口设置分布式同步列表。
(4) 判断是否设置成功。
示例代码如下:
let context = featureAbility.getContext();
context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666, function (result) {
console.info(`result.requestCode=${result.requestCode}`)
})
let promise = rdbStore.setDistributedTables(["test"])
promise.then(() => {
console.info("setDistributedTables success.")
}).catch((err) => {
console.info("setDistributedTables failed.")
})
- 分布式数据同步。
(1) 构造用于同步分布式表的谓词对象,指定组网内的远程设备。
(2) 调用同步数据的接口。
(3) 判断数据同步是否成功。
示例代码如下:
let predicate = new data_rdb.RdbPredicates('test')
predicate.inDevices(['12345678abcde'])
let promise = rdbStore.sync(data_rdb.SyncMode.SYNC_MODE_PUSH, predicate)
promise.then((result) => {
console.log('sync done.')
for (let i = 0; i < result.length; i++) {
console.log('device=' + result[i][0] + 'status=' + result[i][1])
}
}).catch((err) => {
console.log('sync failed')
})
- 分布式数据订阅。
(1) 调用分布式数据订阅接口,注册数据库的观察者。
(2) 当分布式数据库中的数据发生更改时,将调用回调。
示例代码如下:
function storeObserver(devices) {
for (let i = 0; i < devices.length; i++) {
console.log('device=' + devices[i] + 'data changed')
}
}
try {
rdbStore.on('dataChange', data_rdb.SubscribeType.SUBSCRIBE_TYPE_REMOTE, storeObserver)
} catch (err) {
console.log('register observer failed')
}
- 跨设备查询。
1) 根据本地表名获取指定远程设备的分布式表名。
(2) 调用结果集接口,返回查询结果。
示例代码如下:
let tableName = rdbStore.obtainDistributedTableName(deviceId, "test");
let resultSet = rdbStore.querySql("SELECT * FROM " + tableName)