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

概述

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

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

基本概念

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

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

运作机制

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


约束限制

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

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

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

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


导入模块

import relationalStore from '@ohos.data.relationalStore'

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

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

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

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


relationalStore.getRdbStore

getRdbStore(context: Context, config: StoreConfig): Promise<RdbStore>

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

参数列表

context:应用的上下文

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

返回值

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

示例

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

deleteRdbStore(context: Context, name: string): Promise<void>

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

参数列表

context:应用的上下文

name: 数据库名称

返回值

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

示例

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

insert(table: string, values: ValuesBucket):Promise<number>

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

参数列表

table:指定的目标表名

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

返回值

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

示例

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

batchInsert(table: string, values: Array<ValuesBucket>):Promise<number>

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

参数列表

table:指定的目标表名

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

返回值

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

示例

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

update(values: ValuesBucket, predicates: RdbPredicates):Promise<number>

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

参数列表

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

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

返回值

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

示例

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

delete(predicates: RdbPredicates):Promise<number>

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

参数列表

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

返回值

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

示例

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

query(predicates: RdbPredicates, columns?: Array<string>):Promise<ResultSet>

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

参数列表

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

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

返回值

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

示例

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

querySql(sql: string, bindArgs?: Array<ValueType>):Promise<ResultSet>

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

参数列表

sql:指定要执行的SQL语句

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

返回值

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

示例

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对象

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

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

getColumnIndex(columnName: string): number

示例

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

转到结果集的下一行

goToNextRow(): boolean

示例

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
以字节数组的形式获取当前行中指定列的值

getBlob(columnIndex: number): Uint8Array
const codes = resultSet.getBlob(resultSet.getColumnIndex("CODES"));

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

getString(columnIndex: number): string
const name = resultSet.getString(resultSet.getColumnIndex("NAME"));

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

getLong(columnIndex: number): number
const age = resultSet.getLong(resultSet.getColumnIndex("AGE"));

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

getDouble(columnIndex: number): number
const salary = resultSet.getDouble(resultSet.getColumnIndex("SALARY"));

isColumnNull

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

isColumnNull(columnIndex: number): boolean

示例

const isColumnNull = resultSet.isColumnNull(resultSet.getColumnIndex("CODES"));

close

关闭结果集

close(): void

示例

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}`);
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/279742.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

18个惊艳的可视化大屏(第28辑):房产楼盘领域

在房产楼盘领域&#xff0c;可视化的大屏可以提供以下九大价值&#xff1a; 展示楼盘信息 可视化的大屏可以用于展示楼盘的基本信息&#xff0c;包括楼盘名称、位置、户型、价格、面积等&#xff0c;帮助潜在客户快速了解楼盘的特点和优势。 展示楼盘效果图 通过大屏展示楼盘…

load函数无法正常加载CUDA扩展的问题(程序在某一行突然卡死,也不报错,也不停止运行就可以考虑这个原因)

背景&#xff1a;在服务器上跑代码的时候&#xff0c;有时候会遇到程序在某一行代码卡死(阻塞)&#xff0c;既不报错&#xff0c;也不停止运行&#xff0c;就堵在那里。 此时就可以考虑是代码在哪里碰到了load函数&#xff0c;load函数无法正常加载CUDA扩展的问题。 下面以碰到…

MFC界面美化第三篇----自绘按钮(重绘按钮)

1.前言 最近发现读者对我的mfc美化的专栏比较感兴趣&#xff0c;因此在这里进行续写&#xff0c;这里我会计划写几个连续的篇章&#xff0c;包括对MFC按钮的美化&#xff0c;菜单栏的美化&#xff0c;标题栏的美化&#xff0c;list列表的美化&#xff0c;直到最后形成一个完整…

S2-066漏洞分析与复现(CVE-2023-50164)

Foreword 自struts2官方纰漏S2-066漏洞已经有一段时间&#xff0c;期间断断续续地写&#xff0c;直到最近才完成&#xff0c;o(╥﹏╥)o。羞愧地回顾一下官方通告&#xff1a; 2023.12.9发布&#xff0c;编号CVE-2023-50164&#xff0c;主要影响版本是 2.5.0-2.5.32 以及 6.0…

[薅羊毛活动]体验AI编码和开盲盒

​​​​​​​通义灵码 体验 AI 编码&#xff0c;开 AI 盲盒 上面是我的邀请码,直接点击 活动说明 【活动玩法一】“体验AI编码、领取AI盲盒”活动玩法 玩法简述&#xff1a;用户进入活动页面后&#xff0c;随机参与或体验活动页面中通义灵码的任一场景&#xff0c;即可获…

软件测评中心:进行科技成果鉴定测试的注意事项和好处简析

软件产品科技成果鉴定是有效评价科技成果质量和水平的方法之一&#xff0c;也是鼓励科技成果通过市场竞争等方式得到有效的评价和认可&#xff0c;可以推动科技成果的进步和转化。 一、进行科技成果鉴定测试时的注意事项&#xff1a;   1、应由具备一定资质和能力的专业机构…

VS code配置免密连接Linux服务器

1. 服务器端 1.1 安装OpensSSH sudo apt install openssh-server 1.2 开启ssh服务 使用下面的命令查看是否开启了ssh&#xff1a; service ssh status 或者 sudo systemctl status ssh 只要看到绿色高亮的active(running)就是开启了ssh 如果没有开启&#xff0c;则使用…

如何用 Rust Reqwest 写一个Web 爬虫?

用 Rust Reqwest 编写 Web 爬虫 您是否曾考虑过建立自己的 潜在业务数据库&#xff0c;用于潜在客户开发或产品价格数据&#xff0c;以便您可以毫不费力地以最便宜的价格获得产品&#xff1f;网络爬虫可以让您无需亲自执行任何手动工作即可做到这一点。Rust通过允许显式地处理错…

MD5算法:密码学中的传奇

title: MD5算法&#xff1a;密码学中的传奇 date: 2024/3/15 20:08:07 updated: 2024/3/15 20:08:07 tags: MD5起源算法原理安全分析优缺点比较技术改进示例代码应用趋势 MD5算法起源&#xff1a; MD5&#xff08;Message Digest Algorithm 5&#xff09;算法是由MIT的计算机…

【数据结构】哈希表与哈希桶

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.概念 2.哈希冲突…

Vulnhub靶机渗透:DC-7打靶记录

前言 自信自强&#xff0c;来自于不怕苦、不怕难的积淀。宝剑锋从磨砺出&#xff0c;梅花香自苦寒来&#xff1b;任何美好理想&#xff0c;都离不开筚路蓝缕、手胼足胝的艰苦奋斗&#xff01; 靶场介绍 DC-7是一个初中级的靶场&#xff0c;需要具备以下前置知识&#xff1a;…

DevEco Studio 项目创建

安装DevEco Studio后开始使用&#xff0c;双击桌面DevEco Studio 快捷方式弹出界面&#xff1a; 选择Application —> Empty Ability&#xff0c;点击Next 项目配置 Project name&#xff1a;工程的名称&#xff0c;可以自定义&#xff0c;由大小写字母、数字和下划线组成。…

『运维心得』BPC-EPM-AddIn专家看过来

目录 系统版本问题 安装顺序问题 framework问题 vstor_redis问题 dll问题 一个小彩蛋 总结 最近在搞BPC&#xff0c;安装Office所需的EPM-AddIn的过程中&#xff0c;碰到了一些奇怪的问题。 查了BPC专家提供的安装说明文档&#xff0c;文档里要么没有提到我们碰到的问题…

简介:使用TensorFlow实现python简版神经网络模型

如果你想进一步深入AI编程的魔法世界&#xff0c;那么TensorFlow和PyTorch这两个深度学习框架将是你的不二之选。它们可以帮助你构建更加复杂的神经网络模型&#xff0c;实现图像识别、语音识别等高级功能。 模型原理&#xff1a;神经网络是一种模拟人脑神经元结构的计算模型&a…

osgEarth学习笔记3-第二个Osg QT程序

原文链接 打开QT Creator&#xff0c;新建一个窗口项目。 QT版本如下&#xff1a; 修改pro文件 QT core gui greaterThan(QT_MAJOR_VERSION, 4): QT widgets CONFIG c11 DEFINES QT_DEPRECATED_WARNINGS SOURCES \main.cpp \mainwindow.cpp HEADERS \mainwindow…

长安链团队论文入选国际顶会Usenix Security 2024

零知识证明是区块链扩容和隐私保护的关键前沿技术&#xff0c;其天然具备完备性、可靠性和零知识性的特点&#xff0c;是提升区块链交易吞吐量与可扩展性、在验证用户身份的同时保护用户数据隐私&#xff0c;实现复杂计算不可或缺的关键技术。基于零知识证明技术实现高兼容性、…

Linux——进程信号(二)

目录 1、阻塞信号 1.1、信号其他相关常见概念 1.2、在内核中的表示 1.3、sigset_t 1.4、信号集操作函数 2、捕捉信号 2.1、内核如何捕捉信号 5.2、sigaction 1、阻塞信号 1.1、信号其他相关常见概念 实际执行信号的处理动作被称为信号递达&#xff08;Delivery&#x…

迈向容错新时代!PASQAL发布最新技术路线图

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 编辑丨慕一 编译/排版丨沛贤 深度好文&#xff1a;1200字丨8分钟阅读 近日&#xff0c;法国中性原子量子计算公司PASQAL发布了最新技术路线图&#xff0c;概述了其在硬件、业务场景用例及进一…

v3-admin-vite 整合pont

需求 目前后端的Admin模板使用的是v3-admin-vite&#xff0c;需要整合pont接口&#xff0c;方便前后端统一一体化开发 安装PONT 按照官方的文档&#xff0c;将pont engine安装好&#xff0c;然后在项目根目录执行pont start。注意生成代码路径要修改一下&#xff0c;因为v3-a…

【区间、栈】算法例题

目录 六、区间 48. 汇总区间 ① 49. 合并区间 ② 50. 插入区间 ② 51. 用最少数量的箭引爆气球 ② 七、栈 52. 有效的括号 ① 53. 简化路径 ② 54. 最小栈 ② 55. 逆波兰表达式求值 ② √- 56. 基本计算器 ③ 六、区间 48. 汇总区间 ① 给定一个 无重复元素 的 …