HarmonyOS7 数据持久化 relationalStore:数据库实战

文章目录

前言

有些数据不能丢:用户的笔记、离线缓存的订单、本地的聊天记录。这些得存进本地数据库,关掉 app 再打开还在。

HarmonyOS 提供了 relationalStore(关系型数据库,底层就是 SQLite)。这篇文章我用一个"待办事项"的小例子,把建库、建表、增删改查完整走一遍。跟着敲,你就能上手本地数据库。

第一步:建库

typescript 复制代码
import { relationalStore } from '@kit.ArkData'
import { BusinessError } from '@kit.BasicServicesKit'

let db: relationalStore.RdbStore

async function initDB() {
  const cfg: relationalStore.StoreConfig = {
    name: 'todo.db',          // 数据库文件名
    securityLevel: relationalStore.SecurityLevel.S1
  }
  db = await relationalStore.getRdbStore(getContext(), cfg)
}

讲解:

  • getRdbStore 是异步的,拿到一个 RdbStore 实例(就是你的"数据库连接")。
  • securityLevel 是安全等级,普通本地数据用 S1 足够;涉及隐私的用更高等级。
  • 记得 await,建库是耗时的。

第二步:建表

表结构用 SQL 语句定义。建议在 initDB 之后执行一次建表:

代码实现

typescript 复制代码
await db.executeSql(
  `CREATE TABLE IF NOT EXISTS todo (
     id INTEGER PRIMARY KEY AUTOINCREMENT,
     title TEXT NOT NULL,
     done INTEGER DEFAULT 0,
     createTime TEXT
  )`
)
  • IF NOT EXISTS:保证重复调用不会报错(app 第二次启动表已存在)。
  • done INTEGER:SQLite 没有布尔,用 0/1 表示未完成/完成。
  • 字段类型 TEXT/INTEGER 是标准 SQL,写过别的数据库的一看就懂。

第三步:增(插入)

ValuesBucket 装一行数据,再 insert

核心代码

typescript 复制代码
import { ValuesBucket } from '@kit.ArkData'

async function addTodo(title: string) {
  const value: ValuesBucket = {
    title: title,
    done: 0,
    createTime: new Date().toISOString()
  }
  await db.insert('todo', value)
}

ValuesBucket 本质是个键值对对象,键对应表里字段名。插入后自增 id 自动生成。

第四步:查(查询)

typescript 复制代码
async function getAll(): Promise<Todo[]> {
  const predicates = new relationalStore.RdbPredicates('todo')
  predicates.orderByDesc('createTime')   // 按时间倒序
  const result = await db.query(predicates, ['id', 'title', 'done'])
  // result 是 ResultSet,需要手动转成数组
  const list: Todo[] = []
  while (result.goToNextRow()) {
    list.push({
      id: result.getLong(result.getColumnIndex('id')),
      title: result.getString(result.getColumnIndex('title')),
      done: result.getLong(result.getColumnIndex('done')) === 1
    })
  }
  result.close()
  return list
}

要点:

  • RdbPredicates 是查询条件构造器,orderByDesc 排序。
  • query 返回的是 ResultSet(游标),要用 goToNextRow() + getXXX() 一行行取,最后 close() 释放。
  • 转成普通数组后,UI 才好用 ForEach 渲染。

第五步:改和删

typescript 复制代码
async function toggle(id: number, done: boolean) {
  const value: ValuesBucket = { done: done ? 1 : 0 }
  const p = new relationalStore.RdbPredicates('todo')
  p.equalTo('id', id)
  await db.update(value, p)    // 按条件更新
}

async function remove(id: number) {
  const p = new relationalStore.RdbPredicates('todo')
  p.equalTo('id', id)
  await db.delete(p)           // 按条件删除
}
  • 改和删都用 RdbPredicates 指定"哪一行"(equalTo('id', id))。
  • 更新时只放要改的字段,其余不动。

常见误区(小白必踩)

误区 说明
建表漏 IF NOT EXISTS app 第二次启动表已存在,再 CREATE 直接报错。务必加上。
ResultSet 不 close() 查询返回的游标占资源,用完必须 close(),否则泄漏。
忘了主键自增 没设 AUTOINCREMENT,插入重复 id 会冲突。需要唯一标识就用自增主键。

下面这段代码可以直接复制到 DevEco Studio 里运行。建议你边读边敲,改一改文末「动手改一改」里的参数,亲眼看看效果。

完整可运行示例:relationalStore 建表与增查

演示本地关系型数据库的最小闭环:建表、插入、查询。

完整示例

typescript 复制代码
// 关系型数据库:建表 + 插入 + 查询
import { relationalStore } from '@kit.ArkData'

const SQL_CREATE = `CREATE TABLE IF NOT EXISTS user (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  age INTEGER
)`

async function demo(db: relationalStore.RdbStore) {
  await db.executeSql(SQL_CREATE)                 // 建表(幂等)
  await db.insert('user', { name: '小明', age: 18 }) // 插入一行
  const rs = await db.query('user', ['name', 'age'])  // 查询
  while (rs.goToNextRow()) {
    console.info('name=' + rs.getString(0) + ' age=' + rs.getLong(1))
  }
  rs.close()
}

你会看到什么 :运行后 Log 里打印出 name=小明 age=18。表已持久化,下次启动应用数据还在。

动手改一改

  • age: 18 改成 age: 20,再查一次,验证已落库。
  • db.delete('user', ...) 实现按条件删除。
  • 给查询加 WHERE age > 16 的 predicates,做条件过滤。

写在最后

relationalStore 看着 API 多,其实就五个动作:建库、建表、增、查、改删。它和普通 SQLite 一模一样,会 SQL 就会这个。适合存"结构固定、要查询排序"的数据。

如果只是存一个用户名、一个开关,用不着上数据库------下一篇讲的 Preferences 更轻。选对存储方式,比会写代码更重要。

相关推荐
冰茶丿1 小时前
状态机在嵌入式系统中的应用:不只是switch-case这么简单
数据库·嵌入式硬件·mongodb
AIHR数智引擎1 小时前
15%对撞40%:WEF白皮书里的AI组织隐忧
数据库·人工智能·经验分享·职场和发展·aihr
大师兄66681 小时前
HarmonyOS7 HTTP 网络请求封装:统一拦截器实战
网络·网络协议·http·arkui·harmonyos7·实战讲解
卓怡学长1 小时前
w261springboot基于web学校课程管理系统
java·数据库·spring boot·spring·intellij-idea
嘉泰姆半导体官方1 小时前
CXAR41337C 双通道数字音频功放 | 2×20W | EQ+DRC | I²S | MCLK-Less - 嘉泰姆电子
前端·javascript·数据库
风华圆舞1 小时前
鸿蒙HarmonyOS矩阵加载动效实战 —— 从「假旋转」到可复用的波前反馈组件
华为·矩阵·harmonyos·arkui·gradientspin·波前动效·oklab
不坑老师2 小时前
怎么在Word中制作汉字书写笔顺——不坑盒子汉字笔顺步骤在小学低段识字教学中的应用
前端·数据库·人工智能·word·excel·office
大师兄66682 小时前
HarmonyOS7 显式动画与手势:拖拽回弹效果实现
arkui·harmonyos7·实战讲解
苍狼唤2 小时前
SQL+C# 增删改查(练习)
数据库·sql·c#