当前位置: 首页 > news >正文

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 | 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: '停止录制' })
        })

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

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

相关文章:

  • PPT制作,分享下2025年国内外做PPT的AI工具,一健生成PPT
  • 【RabbitMQ】
  • 高精度加减乘除 + R 格式
  • windows免密ssh登录linux
  • 核函数(机器学习深度学习)
  • (UI自动化测试web端)第三篇:元素的常用操作方法_鼠标操作
  • CF每日5题Day2(1400)
  • C语言代码如何操作硬件?
  • 量子计算的黎明:从理论到现实的突破之旅
  • 《Python实战进阶》No37: 强化学习入门:Q-Learning 与 DQN
  • 2025年人工智能产业TOP10有哪些省份?人工智能产业发展前景如何?
  • HarmonyOS NEXT 鸿蒙中手写和使用第三方仓库封装Logger打印工具
  • 04 单目标定实战示例
  • MySQL 用户权限与安全管理
  • 5G网络中CPE和ACS
  • 优雅的开始一个Python项目
  • Windows 我的世界 Minecraft 服务器搭建,Fabric 模组搭建教程(内网穿透)
  • 2025年渗透测试面试题总结-某快手-安全工程师(题目+回答)
  • 【Git 暂存操作与升级应用指南】
  • 华为GaussDB数据库的手动备份与还原操作介绍
  • 滤芯网站怎么做/做seo需要用到什么软件
  • 正规网站制作公司哪里有/网站建设方案设计书
  • 团购网站单页模板/卢松松外链工具
  • 西安网站推广/上热门最火标题
  • 现货交易平台的新型骗局/网站seo是干什么的
  • 做创意礼品的网站/百度快照是什么