【鸿蒙HarmonyOS开发笔记】应用数据持久化之通过关系型数据库实现数据持久化

概述

关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。不支持Worker线程。

关系型数据库基于SQLite组件,适用于存储包含复杂关系数据的场景,比如一个班级的学生信息,需要包括姓名、学号、各科成绩等,又或者公司的雇员信息,需要包括姓名、工号、职位等,由于数据之间有较强的对应关系,复杂程度更高,此时需要使用关系型数据库来持久化保存数据。

基本概念

谓词:数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。

结果集:指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便地拿到用户想要的数据

运作机制

关系型数据库对应用提供通用的操作接口,底层使用SQLite作为持久化存储引擎,支持SQLite具有的数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。


约束限制

系统默认日志方式是WAL(Write Ahead Log)模式,系统默认落盘方式是FULL模式。

数据库中连接池的最大数量是4个,用以管理用户的读操作。

为保证数据的准确性,数据库同一时间只能支持一个写操作。

当应用被卸载完成后,设备上的相关数据库文件及临时文件会被自动清除


导入模块

typescript 复制代码
import relationalStore from '@ohos.data.relationalStore'

该模块提供以下关系型数据库相关的常用功能:

RdbPredicates: 数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。

RdbStore :提供管理关系数据库(RDB)方法的接口。

ResultSet:提供用户调用关系型数据库查询接口之后返回的结果集合。


relationalStore.getRdbStore

typescript 复制代码
getRdbStore(context: Context, config: StoreConfig): Promise<RdbStore>

获得一个相关的RdbStore,操作关系型数据库,用户可以根据自己的需求配置RdbStore的参数,然后通过RdbStore调用相关接口可以执行相关的数据操作,使用Promise异步回调。

参数列表

context:应用的上下文

config: 与此RDB存储相关的数据库配置。主要参数:name 数据库文件名,也是数据库唯一标识符,securityLevel设置数据库安全级别 详细请看官方文档

返回值

Promise<RdbStore>:Promise对象,返回RdbStore对象。

示例

typescript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility'

class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage) {
    var store;
    const STORE_CONFIG = {
      name: "RdbTest.db",
      securityLevel: relationalStore.SecurityLevel.S1
    };
        
    let promise = relationalStore.getRdbStore(this.context, STORE_CONFIG);
    promise.then(async (rdbStore) => {
      store = rdbStore;
      console.info(`Get RdbStore successfully.`)
    }).catch((err) => {
      console.error(`Get RdbStore failed, code is ${err.code},message is ${err.message}`);
    })
  }
}

relationalStore.deleteRdbStore

typescript 复制代码
deleteRdbStore(context: Context, name: string): Promise<void>

使用指定的数据库文件配置删除数据库,使用Promise异步回调。

参数列表

context:应用的上下文

name: 数据库名称

返回值

Promise<void>:无返回结果的Promise对象。

示例

typescript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility'

class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage){
    let promise = relationalStore.deleteRdbStore(this.context, "RdbTest.db");
    promise.then(()=>{
      console.info(`Delete RdbStore successfully.`);
    }).catch((err) => {
      console.error(`Delete RdbStore failed, code is ${err.code},message is ${err.message}`);
    })
  }
}

RdbStore

提供管理关系数据库( RDB)方法的接口。

在使用以下相关接口前,请使用executeSql接口初始化数据库表结构和相关数据


insert

typescript 复制代码
insert(table: string, values: ValuesBucket):Promise<number>

向目标表中插入一行数据,使用Promise异步回调。

参数列表

table:指定的目标表名

values: 表示要插入到表中的数据行

返回值

Promise<number>:Promise对象。如果操作成功,返回行ID;否则返回-1

示例

typescript 复制代码
const valueBucket = {
  "NAME": "Lisa",
  "AGE": 18,
  "SALARY": 100.5,
  "CODES": new Uint8Array([1, 2, 3, 4, 5]),
};
let promise = store.insert("EMPLOYEE", valueBucket);
promise.then((rowId) => {
  console.info(`Insert is successful, rowId = ${rowId}`);
}).catch((err) => {
  console.error(`Insert is failed, code is ${err.code},message is ${err.message}`);
})

batchInsert

typescript 复制代码
batchInsert(table: string, values: Array<ValuesBucket>):Promise<number>

向目标表中插入一组数据,使用Promise异步回调。

参数列表

table:指定的目标表名

values: 表示要插入到表中的一组数据

返回值

Promise<number>:Promise对象。如果操作成功,返回插入的数据个数;否则返回-1

示例

typescript 复制代码
const valueBucket1 = {
  "NAME": "Lisa",
  "AGE": 18,
  "SALARY": 100.5,
  "CODES": new Uint8Array([1, 2, 3, 4, 5])
};
const valueBucket2 = {
  "NAME": "Jack",
  "AGE": 19,
  "SALARY": 101.5,
  "CODES": new Uint8Array([6, 7, 8, 9, 10])
};
const valueBucket3 = {
  "NAME": "Tom",
  "AGE": 20,
  "SALARY": 102.5,
  "CODES": new Uint8Array([11, 12, 13, 14, 15])
};

let valueBuckets = new Array(valueBucket1, valueBucket2, valueBucket3);
let promise = store.batchInsert("EMPLOYEE", valueBuckets);
promise.then((insertNum) => {
  console.info(`batchInsert is successful, the number of values that were inserted = ${insertNum}`);
}).catch((err) => {
  console.error(`batchInsert is failed, code is ${err.code},message is ${err.message}`);
})

update

typescript 复制代码
update(values: ValuesBucket, predicates: RdbPredicates):Promise<number>

根据RdbPredicates的指定实例对象更新数据库中的数据,使用Promise异步回调。

参数列表

values:指示数据库中要更新的数据行。键值对与数据库表的列名相关联

predicates: RdbPredicates的实例对象指定的更新条件

返回值

Promise<number>:Promise对象。返回受影响的行数

示例

typescript 复制代码
const valueBucket = {
  "NAME": "Rose",
  "AGE": 22,
  "SALARY": 200.5,
  "CODES": new Uint8Array([1, 2, 3, 4, 5]),
};
let predicates = new relationalStore.RdbPredicates("EMPLOYEE");
predicates.equalTo("NAME", "Lisa");
let promise = store.update(valueBucket, predicates);
promise.then(async (rows) => {
  console.info(`Updated row count: ${rows}`);
}).catch((err) => {
  console.error(`Updated failed, code is ${err.code},message is ${err.message}`);
})

delete

typescript 复制代码
delete(predicates: RdbPredicates):Promise<number>

根据RdbPredicates的指定实例对象从数据库中删除数据,使用Promise异步回调。

参数列表

predicates:RdbPredicates的实例对象指定的删除条件

返回值

Promise<number>:Promise对象。返回受影响的行数

示例

typescript 复制代码
let predicates = new relationalStore.RdbPredicates("EMPLOYEE");
predicates.equalTo("NAME", "Lisa");
let promise = store.delete(predicates);
promise.then((rows) => {
  console.info(`Delete rows: ${rows}`);
}).catch((err) => {
  console.error(`Delete failed, code is ${err.code},message is ${err.message}`);
})

query

typescript 复制代码
query(predicates: RdbPredicates, columns?: Array<string>):Promise<ResultSet>

根据指定条件查询数据库中的数据,使用Promise异步回调。

参数列表

predicates:RdbPredicates的实例对象指定的查询条件

columns:表示要查询的列。如果值为空,则查询应用于所有列。

返回值

Promise<ResultSet>:Promise对象。如果操作成功,则返回ResultSet对象

示例

typescript 复制代码
let predicates = new relationalStore.RdbPredicates("EMPLOYEE");
predicates.equalTo("NAME", "Rose");
let promise = store.query(predicates, ["ID", "NAME", "AGE", "SALARY", "CODES"]);
promise.then((resultSet) => {
console.info(`ResultSet column names: ${resultSet.columnNames}`);
console.info(`ResultSet column count: ${resultSet.columnCount}`);
}).catch((err) => {
console.error(`Query failed, code is ${err.code},message is ${err.message}`);
})

querySql

typescript 复制代码
querySql(sql: string, bindArgs?: Array<ValueType>):Promise<ResultSet>

根据指定SQL语句查询数据库中的数据,使用Promise异步回调。

参数列表

sql:指定要执行的SQL语句

bindArgs:SQL语句中参数的值。当sql参数语句完整时,该参数不填。

返回值

Promise<ResultSet>:Promise对象。如果操作成功,则返回ResultSet对象

示例

typescript 复制代码
let promise = store.querySql("SELECT * FROM EMPLOYEE CROSS JOIN BOOK WHERE BOOK.NAME = 'sanguo'");
promise.then((resultSet) => {
  console.info(`ResultSet column names: ${resultSet.columnNames}`);
  console.info(`ResultSet column count: ${resultSet.columnCount}`);
}).catch((err) => {
  console.error(`Query failed, code is ${err.code},message is ${err.message}`);
})

ResultSet

提供通过查询数据库生成的数据库结果集的访问方法。结果集是指用户调用关系型数据库查询接口之后返回的结果集合,提供了多种灵活的数据访问方式,以便用户获取各项数据

使用说明

首先需要获取resultSet对象

typescript 复制代码
let resultSet = null;
let predicates = new relationalStore.RdbPredicates("EMPLOYEE");
predicates.equalTo("AGE", 18);
let promise = store.query(predicates, ["ID", "NAME", "AGE", "SALARY", "CODES"]);
promise.then((result) => {
  resultSet = result;
  console.info(`resultSet columnNames: ${resultSet.columnNames}`);
  console.info(`resultSet columnCount: ${resultSet.columnCount}`);
});

属性如下

columnNames

获取结果集中所有列的名称。


columnCount

获取结果集中的列数。


rowCount

获取结果集中的行数。


rowIndex

获取结果集当前行的索引。


isAtFirstRow

检查结果集是否位于第一行。


isAtLastRow

检查结果集是否位于最后一行。


isEnded

检查结果集是否位于最后一行之后。


isStarted

检查指针是否移动过。


isClosed

检查当前结果集是否关闭。


常用的方法

getColumnIndex

根据指定的列名获取列索引

typescript 复制代码
getColumnIndex(columnName: string): number

示例

typescript 复制代码
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"));

goToNextRow

转到结果集的下一行

typescript 复制代码
goToNextRow(): boolean

示例

typescript 复制代码
let predicates = new relationalStore.RdbPredicates("EMPLOYEE");
let promise = store.query(predicates, ["ID", "NAME", "AGE", "SALARY", "CODES"]);
promise.then((resultSet) => {
resultSet.goToNextRow();
resultSet.close();
}).catch((err) => {
console.error(`query failed, code is ${err.code},message is ${err.message}`);
});

getBlob

以字节数组的形式获取当前行中指定列的值

typescript 复制代码
getBlob(columnIndex: number): Uint8Array
const codes = resultSet.getBlob(resultSet.getColumnIndex("CODES"));

getString

以字符串形式获取当前行中指定列的值

typescript 复制代码
getString(columnIndex: number): string
const name = resultSet.getString(resultSet.getColumnIndex("NAME"));

getLong

以Long形式获取当前行中指定列的值

typescript 复制代码
getLong(columnIndex: number): number
const age = resultSet.getLong(resultSet.getColumnIndex("AGE"));

getDouble

以double形式获取当前行中指定列的值

typescript 复制代码
getDouble(columnIndex: number): number
const salary = resultSet.getDouble(resultSet.getColumnIndex("SALARY"));

isColumnNull

检查当前行中指定列的值是否为null,如果当前行中指定列的值为null,则返回true,否则返回false

typescript 复制代码
isColumnNull(columnIndex: number): boolean

示例

typescript 复制代码
const isColumnNull = resultSet.isColumnNull(resultSet.getColumnIndex("CODES"));

close

关闭结果集

typescript 复制代码
close(): void

示例

typescript 复制代码
let predicatesClose = new relationalStore.RdbPredicates("EMPLOYEE");
let promiseClose = store.query(predicatesClose, ["ID", "NAME", "AGE", "SALARY", "CODES"]);
promiseClose.then((resultSet) => {
resultSet.close();
}).catch((err) => {
console.error(`resultset close failed, code is ${err.code},message is ${err.message}`);
});
相关推荐
Zzz 小生2 小时前
Claude Code学习笔记(四)-助你快速搭建首个Python项目
大数据·数据库·elasticsearch
黎宇幻生4 小时前
Java全栈学习笔记39
java·笔记·学习
nongcunqq5 小时前
abap 操作 excel
java·数据库·excel
rain bye bye6 小时前
calibre LVS 跑不起来 就将setup 的LVS Option connect下的 connect all nets by name 打开。
服务器·数据库·lvs
爱笑的眼睛117 小时前
我的HarmonyOS百宝箱
华为·harmonyos
2501_919749037 小时前
鸿蒙:创建公共事件、订阅公共事件和退订公共事件
华为·harmonyos
遇印记7 小时前
大二java学习笔记:二维数组
java·笔记·学习
阿里云大数据AI技术7 小时前
云栖实录|MaxCompute全新升级:AI时代的原生数据仓库
大数据·数据库·云原生
不剪发的Tony老师8 小时前
Valentina Studio:一款跨平台的数据库管理工具
数据库·sql
weixin_307779138 小时前
在 Microsoft Azure 上部署 ClickHouse 数据仓库:托管服务与自行部署的全面指南
开发语言·数据库·数据仓库·云计算·azure