【鸿蒙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}`);
});
相关推荐
luckys.one15 小时前
第9篇:Freqtrade量化交易之config.json 基础入门与初始化
javascript·数据库·python·mysql·算法·json·区块链
言之。17 小时前
Django中的软删除
数据库·django·sqlite
汇能感知18 小时前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun18 小时前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
茯苓gao18 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
爱笑的眼睛1118 小时前
HarmonyOS 应用开发新范式:深入探索 Stage 模型与 ArkUI 声明式开发
华为·harmonyos
是誰萆微了承諾18 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
阿里嘎多哈基米18 小时前
SQL 层面行转列
数据库·sql·状态模式·mapper·行转列
抠脚学代码19 小时前
Ubuntu Qt x64平台搭建 arm64 编译套件
数据库·qt·ubuntu
jakeswang19 小时前
全解MySQL之死锁问题分析、事务隔离与锁机制的底层原理剖析
数据库·mysql