HarmonyOS NEXT 鸿蒙中关系型数据库@ohos.data.relationalStore API 9+

核心API

@ohos.data.relationalStore API 9+

数据库

数据库是存储和管理数据的系统

数据库(Database)是一个以特定方式组织、存储和管理数据的集合,通常用于支持各种应用程序和系统的运行。它不仅是存放数据的仓库,还通过一定的规则和结构来确保数据的高效查询和管理。‌

数据库的核心特点

  1. 数据存储‌:数据库可以存储大量数据,从百万条到上亿条不等,且数据按特定规则组织,以提高查询效率。
  2. 数据管理‌:数据库通过数据库管理系统(DBMS)进行统一管理,确保数据的安全性、完整性和一致性。
  3. 数据共享‌:数据库支持多用户同时访问,且数据可以被多个应用程序共享和使用。

数据库的常见类型

  1. 关系型数据库‌:基于关系模型,数据以表格形式存储,支持SQL语言进行复杂查询,如MySQL、Oracle等。
  2. 非关系型数据库(NoSQL)‌:适用于非结构化或半结构化数据,具有更好的横向扩展能力,如MongoDB、Redis等。

鸿蒙的关系型数据库用法 @ohos.data.relationalStore API 9+

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

为保证插入并读取数据成功,建议一条数据不要超过2M。超出该大小,插入成功,读取失败。

大数据量场景下查询数据可能会导致耗时长甚至应用卡死,如有相关操作可参考文档批量数据写数据库场景,且有建议如下:

  • 单次查询数据量不超过5000条。
  • 在TaskPool中查询。
  • 拼接SQL语句尽量简洁。
  • 合理地分批次查询。

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

  • RdbPredicates: 数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
  • RdbStore:提供管理关系数据库(RDB)方法的接口。
  • ResultSet:提供用户调用关系型数据库查询接口之后返回的结果集合。
  • Transaction:提供管理事务对象的接口。

使用数据库封装一个数据库工具,用于存储录音

在之前的文章中,我们完成了一些录音和播放的功能,但是目前只能现录现播。如果我们想把录音数据存起来,这时候用关系型数据库就比较合适。

  1. 首先我们要准备好要存储的数据类型,并且继承数据库提供的“桶”类型ValuesBucket
  2. 要有一个初始化数据库的方法,获取上下文,并判断是否获取到上下文
  3. 如果数据库不存在就创建relationalStore.getRdbStore,存在就不创建
  4. store.executeSql在数据库中创建或打开表,SQL语句可以去用AI生成
  5. 需要增删改查四个方法
  6. 增:直接传入要添加的数据
  7. 删:创建谓词对象,传入Id,根据id找到行,然后删除
  8. 改:创建谓词对象,传入整个对象,找到修改行,更新
  9. 查:创建谓词对象,传入user_Id,采用游标移动取值,循环到没有下一行为止,每一次循环都在数组中追加当前的行,最后返回一个数组。
import { relationalStore, ValuesBucket } from "@kit.ArkData"
import { InterviewAudioItem } from "../../models"export interface InterviewAudioItem extends ValuesBucket {id: number | nulluser_id: stringname: stringpath: stringduration: numbersize: numbercreate_time: number
}class AudioDB {store?: relationalStore.RdbStoretableName = 'success_audio'// 1. 初始化数据库和数据库表async initStore() {// 1.0 获取上下文const ctx = AppStorage.get<Context>('context')if (ctx) {// 1.1 创建数据库// 有则获取, 没有则创建const store = await relationalStore.getRdbStore(ctx, {name: 'interview_audio.db',securityLevel: relationalStore.SecurityLevel.S1})// 1.2 在数据库中创建一张数据库表store.executeSql(`CREATE TABLE IF NOT EXISTS ${this.tableName} (id INTEGER PRIMARY KEY AUTOINCREMENT,user_id TEXT NOT NULL,name TEXT NOT NULL,path TEXT NOT NULL,duration INTEGER NOT NULL,size INTEGER NOT NULL,create_time INTEGER NOT NULL)`)this.store = store}}// 2. 添加一条音频数据async insert(item: InterviewAudioItem) {if (this.store) {const rowId = await this.store.insert(this.tableName, item)if (rowId === undefined || rowId === -1) {return Promise.reject('插入音频数据失败')} else {return Promise.resolve()}}}// 3. 删除一条音频数据async delete(audioId: number) {if (this.store) {const predicates = new relationalStore.RdbPredicates(this.tableName)predicates.equalTo('id', audioId)const rowId = await this.store.delete(predicates)if (rowId === undefined || rowId === -1) {return Promise.reject('删除音频数据失败')} else {return Promise.resolve()}}}// 4. 修改一条音频数据async update(item: InterviewAudioItem) {if (this.store) {const predicates = new relationalStore.RdbPredicates(this.tableName)predicates.equalTo('id', item.id)const rowId = await this.store.update(item, predicates)if (rowId === undefined || rowId === -1) {return Promise.reject('修改音频数据失败')} else {return Promise.resolve()}}}// 5. 根据用户id查询用户所有的录音数据async query(userId: string) {if (this.store) {// 1. 创建一个基于查询条件的谓词对象const predicates = new relationalStore.RdbPredicates(this.tableName)predicates.equalTo('user_id', userId)// 2. 执行数据库查询得到结果集const resultSet = await this.store.query(predicates)if (!resultSet) {return Promise.reject('query fail')}// 3. 采用游标移动取值const list: InterviewAudioItem[] = []// 3.1 如果有下一行, 则继续循环while (resultSet?.goToNextRow()) {list.push(resultSet.getRow() as InterviewAudioItem)}// 3.2 关闭查询结果集resultSet.close()return Promise.resolve(list)}return Promise.reject('暂无数据库')}
}export const audioDB = new AudioDB()

这样一个完整功能的数据库工具就创建好了,那么我们就直接去把录音存到数据库中吧!

在录音页面中使用数据库保存数据

首先在页面开始时初始化数据库

  async aboutToAppear() {await this.getPermission()// 2. 初始化数据库await audioDB.initStore()}

 初始化完成可以在设备管理器中看到三个数据库相关文件

在录制开始的函数中,我们记录下开始时间

在点击结束录制的时候,我们再额外调用一个方法,传入音频类型的项,调用数据库方法插入数据库中。

// 存入数据库方法async onRecordEnd(item: InterviewAudioItem) {await audioDB.insert(item)AlertDialog.show({ message: '录音保存成功' })}Button('停止录制').onClick(() => {this.stopRecord()// 以只读的方式根据路径打开文件const file = fileIo.openSync(this.filePath, fileIo.OpenMode.READ_ONLY)const stat = fileIo.statSync(file.fd)this.onRecordEnd({id: null,user_id: auth.getUser().id,name: dayjs().format('YYYY年MM月DD日_hh点mm分ss秒'),path: this.filePath || '',duration: Date.now() - this.startTime,create_time: Date.now(),size: stat.size})promptAction.showToast({ message: '停止录制' })})

 点击开始录音录制一段时间,然后结束录制

这样一条数据就被插入了数据库表中,对比数据库文件发现,确实比之前大了,就说明已经插入完成,因为没有可视化打开数据库的工具,所有无法具体查看数据表的内容。

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

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

相关文章

步进电机 cia402协议 报文自己的理解 (笔记)

1. cai402 协议是什么 CiA 402 协议&#xff08;CAN in Automation 402&#xff09;&#xff0c;它是工业自动化领域中的一种通信协议&#xff0c;主要用于运动控制&#xff08;如伺服驱动器、步进电机等&#xff09;&#xff08; &#xff09;所属标准 CiA 402 是 CANopen 应用…

鸿蒙摄像机,一场智能安防的“平权革命”

2025的春天&#xff0c;全国各行各业都感受到了普惠AI的魅力。大模型带来的技术平权&#xff0c;让每一个人都能轻松用上AI。 这时候&#xff0c;企业想知道&#xff0c;每时每刻离不开的摄像机&#xff0c;究竟什么时候才能迎来智能技术的平权与普惠。 博思数据研究中心的一份…

解决HuggingFaceEmbeddings模型加载报错:缺少sentence-transformers依赖包

遇到报错 报错信息: Error loading model: Could not import sentence_transformers python package. Please install it with pip install sentence-transformers. 装包信息&#xff1a; pip install modelscope langchain sentence_transformers langchain-huggingface on…

从泛读到精读:合合信息文档解析如何让大模型更懂复杂文档

从泛读到精读&#xff1a;合合信息文档解析如何让大模型更懂复杂文档 一、引言&#xff1a;破解文档“理解力”瓶颈二、核心功能&#xff1a;合合信息的“破局”亮点功能亮点1&#xff1a;复杂图表的高精度解析图表解析&#xff1a;为大模型装上精准“标尺”表格数据精准还原 功…

Python+requests实现接口自动化测试框架

为什么要做接口自动化框架 1、业务与配置的分离 2、数据与程序的分离&#xff1b;数据的变更不影响程序 3、有日志功能&#xff0c;实现无人值守 4、自动发送测试报告 5、不懂编程的测试人员也可以进行测试 正常接口测试的流程是什么&#xff1f; 确定接口测试使用的工具…

信息学奥赛一本通 1514:【例 2】最大半连通子图 | 洛谷 P2272 [ZJOI2007] 最大半连通子图

【题目链接】 ybt 1514&#xff1a;【例 2】最大半连通子图 洛谷 P2272 [ZJOI2007] 最大半连通子图 【题目考点】 1. 图论&#xff1a;强连通分量 缩点 2. 图论&#xff1a;拓扑排序 有向无环图动规 【解题思路】 对于图中任意两顶点u、v&#xff0c;满足u到v或v到u有路径…

Android打aar包问题总结

1、moduleA 依赖 moduleB&#xff0c;将moduleA打包成aar时&#xff0c;未包含 moduleB的resources资源&#xff1b; 方法一&#xff1a;将moduleB的资源&#xff0c;手动拷贝一份到moduleA中&#xff1b; 方法二&#xff1a;使用 fat-aar 插件&#xff1b; 2、fat-aar插件使…

【网络协议】【http】http 简单介绍

【网络协议】【http】http 简单介绍 1 HTTP 头部 HTTP 是一种请求-响应协议&#xff0c;客户端向服务器发送请求&#xff0c;服务器返回响应。 1.1 HTTP 状态码 状态码是服务器返回给客户端的 三位数字代码&#xff0c;用于表示请求的执行结果。 状态码按照首位数字分类&am…

谈谈空间复杂度考量,特别是递归调用栈空间消耗?

空间复杂度考量是算法设计的核心要素之一&#xff0c;递归调用栈的消耗问题在前端领域尤为突出。 以下结合真实开发场景进行深度解析&#xff1a; 一、递归调用栈的典型问题 1. 深层次DOM遍历的陷阱 // 危险操作&#xff1a;递归遍历未知层级的DOM树 function countDOMNode…

LeetCode算法题(Go语言实现)_16

题目 给定一个二进制数组 nums 和一个整数 k&#xff0c;假设最多可以翻转 k 个 0 &#xff0c;则返回执行操作后 数组中连续 1 的最大个数 。 一、代码实现 func longestOnes(nums []int, k int) int {left, zeroCnt, maxLen : 0, 0, 0for right : 0; right < len(nums); …

【数据结构】栈 与【LeetCode】20.有效的括号详解

目录 一、栈1、栈的概念及结构2、栈的实现3、初始化栈和销毁栈4、打印栈的数据5、入栈操作---栈顶6、出栈---栈顶6.1栈是否为空6.2出栈---栈顶 7、取栈顶元素8、获取栈中有效的元素个数 二、栈的相关练习1、练习2、AC代码 个人主页&#xff0c;点这里~ 数据结构专栏&#xff0c…

攻破tensorflow,勇创最佳agent(2)---损失(loss) 准确率(accuracy)问题

实战播: 怎么判定一个模型好不好,你设置的值对不对? 需要再看几个值: 例如: model Sequential()for units in model_structure:model.add(Dense(units, activationrelu))model.add(Dropout(train_config.get(dropout_rate, 0.3)))model.add(Dense(1, activationsigmoid)) 他…

pdfh5 pdf

踩坑1&#xff1a; 渲染失败 &#xff08;1&#xff09;在vue项目中&#xff0c;读取本地的pdf文件需要放到public下static文件夹中&#xff0c;不能放在别的地方&#xff1b; &#xff08;2&#xff09;引用时&#xff0c;不能使用相对路径&#xff0c;因为使用public文件下…

6.5 模拟专题:LeetCode 38. 外观数列

1. 题目链接 LeetCode 38. 外观数列 2. 题目描述 给定一个正整数 n&#xff0c;生成外观数列的第 n 项。外观数列的定义如下&#xff1a; 第 1 项为 "1"。第 n 项是对第 n-1 项的描述。例如&#xff0c;第 2 项描述第 1 项&#xff08;"1"&#xff09;为…

什么是具身智能

具身智能&#xff08;Embodied Intelligence&#xff09;是人工智能与机器人学交叉的前沿领域&#xff0c;强调智能体通过身体与环境的动态交互实现自主学习和进化&#xff0c;其核心在于将感知、行动与认知深度融合‌。通俗地讲&#xff0c;就是机器人或者智能系统在物理环境中…

git命令使用小记(打补丁)

需求&#xff1a;需要从开发分支提取本人提交代码&#xff0c;然后合并到主分支 一、制作补丁包 mkdir -p patches for commit in $(git log commitA..commitB --author"username" --reverse --prettyformat:"%h"); do …

mapbox基础,加载popup弹出窗

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️popup 弹出窗 api1.3.1 ☘️构造函数1.…

C++11--(1)

目录 1.列表初始化 {}初始化 C98中 C11中 内置置类型和自定义类型 创建对象也适用 std::initializer_list 2.变量类型推导 auto C98 C11 decltype nullptr 3.范围for循环 4.STL中一些变化 array 1.创建和初始化 2.访问元素 ​编辑 3.修改操作 4.支持迭代器…

Promise的状态和方法是什么?

Promise 的状态和方法 1. Promise 的状态 一个 Promise 可以处于以下三种状态之一&#xff1a; - Pending&#xff08;待定&#xff09;&#xff1a;初始状态&#xff0c;表示异步操作正在进行中&#xff0c;Promise 还没有被解决或拒绝。 - Fulfilled&#xff08;已完成&…

Windows云服务器支持哪些数据库管理系统?

Windows云服务器因其良好的兼容性和企业级支持&#xff0c;广泛用于网站托管、企业管理系统、金融应用、数据分析等场景。在这些应用中&#xff0c;数据库管理系统(DBMS)起着至关重要的作用。Windows 服务器支持多种数据库&#xff0c;包括关系型数据库(SQL)和非关系型数据库(N…