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

news2025/4/1 5:49:57

核心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 | null
  user_id: string
  name: string
  path: string
  duration: number
  size: number
  create_time: number
}

class AudioDB {
  store?: relationalStore.RdbStore
  tableName = '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.coloradmin.cn/o/2324078.html

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

相关文章

【JavaScript】JavaScript Promises实践指南

【JavaScript】JavaScript Promises实践指南 你了解JavaScript中的Promises吗&#xff1f;这是一个很多人一开始就放弃的主题&#xff0c;但我会尽量让它变得尽可能简单。 1. “Promise”到底是什么&#xff1f; “Promise”是异步编程中的一个基本概念&#xff0c;特别是在J…

git push的时候出现无法访问的解决

fatal: 无法访问 https://github.com/...&#xff1a;gnutls_handshake() failed: Error in the pull function. push的时候没有输入自己的github账号密码&#xff0c;为了解决每次push都要登录github这个问题&#xff0c;采用ssh密钥的方式认证&#xff0c;可以免去每次都输入…

为什么大模型在 OCR 任务上表现不佳?

编者按&#xff1a; 你是否曾经用最先进的大语言模型处理企业文档&#xff0c;却发现它把财务报表中的“$1,234.56”读成了“123456”&#xff1f;或者在处理医疗记录时&#xff0c;将“0.5mg”误读为“5mg”&#xff1f;对于依赖数据准确性的运营和采购团队来说&#xff0c;这…

HCIP(VLAN综合实验)

实验拓补图 实验分析 一、实验目的 掌握VLAN的创建和配置方法理解VLAN在局域网中的作用学习如何通过VLAN实现网络隔离和通信 二、实验环境 交换机&#xff08;SW1、SW2、SW3&#xff09;个人电脑&#xff08;PC1、PC2、PC3、PC4、PC5、PC6&#xff09;路由器&#xff08;R1…

每日算法-250328

记录今天学习和解决的LeetCode算法题。 92. 反转链表 II 题目 思路 本题要求反转链表中从 left 到 right 位置的节点。我们可以采用 头插法 的思路来反转指定区间的链表。 具体来说&#xff0c;我们首先定位到 left 位置节点的前一个节点 prev。然后&#xff0c;从 left 位置…

从 Word 到 HTML:使用 Aspose.Words 轻松实现 Word 文档的高保真转换

从 Word 到 HTML&#xff1a;使用 Aspose.Words 轻松实现 Word 文档的高保真转换 前言一、环境准备二、核心代码实现1. 将 Word 转换为 HTML 文件流2. 优化超链接样式 三、测试效果四、总结 前言 在日常开发中&#xff0c;我们经常需要将 Word 文档转换为 HTML&#xff0c;用于…

RSA 简介及 C# 和 js 实现【加密知多少系列_4】

〇、简介 谈及 RSA 加密算法&#xff0c;我们就需要先了解下这两个专业名词&#xff0c;对称加密和非对称加密。 对称加密&#xff1a;在同一密钥的加持下&#xff0c;发送方将未加密的原文&#xff0c;通过算法加密成密文&#xff1b;相对的接收方通过算法将密文解密出来原文…

机器学习——LightGBM

LightGBM(light gradient boosting machine&#xff0c;轻量梯度提升机)是对XGBoost进行改进的模型版本&#xff0c;其三者之间的演变关系为&#xff1a;GBDT-》XGBoost-》LightGBM&#xff0c;依次对性能进行优化&#xff0c;尽管XGBoost已经很高效了&#xff0c;但是仍然有缺…

故障识别 | 基于改进螂优化算法(MSADBO)优化变分模态提取(VME)结合稀疏最大谐波噪声比解卷积(SMHD)进行故障诊断识别,matlab代码

基于改进螂优化算法&#xff08;MSADBO&#xff09;优化变分模态提取&#xff08;VME&#xff09;结合稀疏最大谐波噪声比解卷积&#xff08;SMHD&#xff09;进行故障诊断识别 一、引言 1.1 机械故障诊断的背景和意义 在工业生产的宏大画卷中&#xff0c;机械设备的稳定运行…

[已解决]服务器CPU突然飙高98%----Java程序OOM问题 (2024.9.5)

目录 问题描述问题排查问题解决参考资料 问题描述 业主单位服务器自8月29日晚上21:00起CPU突然飙高至98%&#xff0c;内存爆满&#xff0c;一直到9月5日&#xff1a; 问题排查 ①执行 top 命令查看Java进程PID top②执行top -Hp PID 命令查看具体的线程情况 top -Hp 3058输入上…

Ai工作流工具有那些如Dify、coze扣子等以及他们是否开源

Dify &#xff08;https://difycloud.com/&#xff09; 核心定位&#xff1a;专业级 LLM 应用开发平台&#xff0c;支持复杂 AI 工作流构建与企业级管理。典型场景&#xff1a;企业智能客服、数据分析系统、复杂自动化流程构建等。适合需要深度定制、企业级管理和复杂 AI 逻辑…

Yolo_v8的安装测试

前言 如何安装Python版本的Yolo&#xff0c;有一段时间不用了&#xff0c;Yolo的版本也在不断地发展&#xff0c;所以重新安装了运行了一下&#xff0c;记录了下来&#xff0c;供参考。 一、搭建环境 1.1、创建Pycharm工程 首先创建好一个空白的工程&#xff0c;如下图&…

软件兼容性测试的矩阵爆炸问题有哪些解决方案

解决软件兼容性测试中的矩阵爆炸问题主要有优先级划分、组合测试方法、自动化测试技术等方案。其中&#xff0c;组合测试方法尤其有效。组合测试通过科学的组合算法&#xff0c;能够显著降低测试用例的数量&#xff0c;同时保持较高的测试覆盖率&#xff0c;例如正交实验设计&a…

嵌入式学习(32)-TTS语音模块SYN6288

一、概述 SYN6288 中文语音合成芯片是北京宇音天下科技有限公司于 2010年初推出的一款性/价比更高,效果更自然的一款中高端语音合成芯片。SYN6288 通过异步串口(UART)通讯方式&#xff0c;接收待合成的文本数据&#xff0c;实现文本到语音(或 TTS 语音)的转换。宇音天下于 2002…

从零到一:打造顶尖生成式AI应用的全流程实战

简介 生成式AI正以前所未有的速度改变我们的世界&#xff0c;从内容创作到智能客服&#xff0c;再到医疗诊断&#xff0c;它正在成为各行各业的核心驱动力。然而&#xff0c;构建一个高效、安全且负责任的生成式AI系统并非易事。本文将带你从零开始&#xff0c;逐步完成一个完整…

Windows 10更新失败解决方法

在我们使用 Windows 时的时候&#xff0c;很多时候遇到系统更新 重启之后却一直提示“我们无法完成更新&#xff0c;正在撤销更改” 这种情况非常烦人&#xff0c;但其实可以通过修改文件的方法解决&#xff0c;并且正常更新到最新版操作系统 01修改注册表 管理员身份运行注…

ubuntu24.04.2 NVIDIA GeForce RTX 4060笔记本安装驱动

https://www.nvidia.cn/drivers/details/242281/ 上面是下载地址 sudo chmod x NVIDIA-Linux-x86_64-570.133.07.run # 赋予执行权限把下载的驱动复制到家目录下&#xff0c;基本工具准备&#xff0c;如下 sudo apt update sudo apt install build-essential libglvnd-dev …

如何快速下载并安装 Postman?

从下载、安装、启动 Postman 这三个方面为大家详细讲解下载安装 Postman 每一步操作&#xff0c;帮助初学者快速上手。 Postman 下载及安装教程(2025最新)

1.1 计算机网络的概念

首先来看什么是计算机网络&#xff0c;关于计算机网络的定义并没有一个统一的标准&#xff0c;不同的教材有 不同的说法&#xff08;这是王道书对于计算机网络的定义&#xff09;&#xff0c;我们可以结合自己的生活经验去体会这个 定义。 可以用不同类型的设备去连接计算机网络…

Blender绘图——旋转曲线(以LCP与RCP为例)

最近在做左旋圆偏振光&#xff08;LCP&#xff09;与右旋圆偏振光&#xff08;RCP&#xff09;的研究&#xff0c;因此需要画出他们的图&#xff0c;接下来我就介绍一下用Blender怎么去画LCP与RCP。 首先你需要下载Blender软件&#xff0c;网上直接能搜到&#xff0c;图标如下…