HarmonyOS 鸿蒙Next关系型数据库设计与操作

HarmonyOS 鸿蒙Next关系型数据库设计与操作 HarmonyOS 提供了哪些数据持久化方案?在需要存储结构化数据时,如何使用关系型数据库 RDB?请详细说明数据库的初始化、表的创建、数据的增删改查操作,以及如何处理数据库版本升级和字段迁移?(问题来源项目案例整理:https://github.com/heqiyuan35-creator/HydroQuiz.git

3 回复

HarmonyOS 数据持久化方案包括:Preferences(轻量键值对)、RDB(关系型数据库)、分布式数据管理等。

数据库初始化

import { relationalStore } from '@kit.ArkData';

const config: relationalStore.StoreConfig = {
  name: 'HydroQuiz.db',
  securityLevel: relationalStore.SecurityLevel.S1
};

this.rdbStore = await relationalStore.getRdbStore(context, config);

创建表和索引

const createTable: string = `
  CREATE TABLE IF NOT EXISTS knowledge_read_records (
    article_id TEXT PRIMARY KEY,
    view_count INTEGER DEFAULT 0,
    read_time INTEGER DEFAULT 0,
    progress INTEGER DEFAULT 0,
    last_read_time INTEGER NOT NULL
  )
`;

await this.rdbStore.executeSql(createTable);
await this.rdbStore.executeSql('CREATE INDEX IF NOT EXISTS idx_read_time ON knowledge_read_records(last_read_time)');

CRUD 操作

// 查询
const predicates = new relationalStore.RdbPredicates('knowledge_read_records');
predicates.equalTo('article_id', articleId);
const resultSet = await store.query(predicates);
// 插入
const valueBucket: relationalStore.ValuesBucket = {
  article_id: articleId,
  view_count: 1,
  last_read_time: Date.now()
};
await store.insert('knowledge_read_records', valueBucket);
// 更新
await store.update(valueBucket, predicates);
// 删除
await store.delete(predicates);

版本升级迁移

// 添加新字段(兼容旧版本)
try {
  await this.rdbStore.executeSql('ALTER TABLE wrong_questions ADD COLUMN note TEXT DEFAULT \'\'');
} catch (e) {
  // 字段已存在,忽略错误
}

更多关于HarmonyOS 鸿蒙Next关系型数据库设计与操作的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


HarmonyOS Next关系型数据库基于SQLite实现,支持本地数据存储。使用关系型数据库(RDB)接口进行设计,通过定义实体类映射数据表结构,并利用注解配置主键、字段等属性。操作时通过RdbStore实例执行SQL语句,包括增删改查及事务处理。数据以表形式组织,支持跨设备同步。开发者需在配置文件中声明数据库权限。

HarmonyOS Next提供了多种数据持久化方案,包括:轻量级偏好数据库(Preferences)、关系型数据库(RDB)以及分布式数据对象(DataObject)。对于需要存储结构化数据、支持复杂查询和事务的场景,关系型数据库(RDB)是首选方案。

以下是基于HarmonyOS Next的关系型数据库(RDB)设计与操作的核心步骤:

1. 数据库初始化与配置

首先,需要在module.json5文件中声明数据库的访问权限。

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.DISTRIBUTED_DATASYNC"
      }
    ]
  }
}

然后,在应用代码中通过RdbStoreConfigRdbOpenCallback进行初始化。

import { relationalStore, RdbStore, RdbStoreConfig } from '@kit.RelationalStoreKit';

// 配置数据库
let config: RdbStoreConfig = {
  name: 'myDatabase.db', // 数据库名称
  securityLevel: relationalStore.SecurityLevel.S1 // 安全级别
};

// 定义数据库版本和表结构创建/升级逻辑
let openCallback: relationalStore.RdbOpenCallback = {
  onOpen: (store: RdbStore) => {
    console.info('RDB opened');
  },
  onCreate: (store: RdbStore) => {
    // 首次创建数据库时执行
    store.executeSql('CREATE TABLE IF NOT EXISTS USER (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INTEGER)');
    console.info('RDB created and table initialized');
  },
  onUpgrade: (store: RdbStore, oldVersion: number, newVersion: number) => {
    // 数据库版本升级时执行,用于字段迁移
    // 示例:从版本1升级到版本2,新增SCORE字段
    if (oldVersion < 2) {
      store.executeSql('ALTER TABLE USER ADD COLUMN SCORE INTEGER DEFAULT 0');
    }
    console.info(`RDB upgraded from v${oldVersion} to v${newVersion}`);
  }
};

// 获取RDB实例
let rdbStore: RdbStore | undefined = undefined;
try {
  relationalStore.getRdbStore(context, config).then((store: RdbStore) => {
    rdbStore = store;
    console.info('RDB store obtained');
  });
} catch (err) {
  console.error(`Failed to get RDB store. Code:${err.code}, message:${err.message}`);
}

2. 数据操作(增删改查)

假设已初始化rdbStore实例,并存在USER表。

插入数据(Create)

import { ValuesBucket } from '@kit.RelationalStoreKit';

let valueBucket: ValuesBucket = {
  'NAME': '张三',
  'AGE': 25,
  'SCORE': 90
};
try {
  let rowId = await rdbStore.insert('USER', valueBucket);
  console.info(`Insert succeeded, rowId: ${rowId}`);
} catch (err) {
  console.error(`Insert failed. Code:${err.code}, message:${err.message}`);
}

查询数据(Read)

import { RdbPredicates } from '@kit.RelationalStoreKit';

let predicates = new relationalStore.RdbPredicates('USER');
predicates.equalTo('NAME', '张三'); // 查询条件:NAME = '张三'
try {
  let resultSet = await rdbStore.query(predicates, ['ID', 'NAME', 'AGE', 'SCORE']);
  console.info(`Query succeeded, resultSet row count: ${resultSet.rowCount}`);
  while (resultSet.goToNextRow()) {
    let id = resultSet.getDouble(resultSet.getColumnIndex('ID'));
    let name = resultSet.getString(resultSet.getColumnIndex('NAME'));
    let age = resultSet.getLong(resultSet.getColumnIndex('AGE'));
    let score = resultSet.getLong(resultSet.getColumnIndex('SCORE'));
    console.info(`ID: ${id}, NAME: ${name}, AGE: ${age}, SCORE: ${score}`);
  }
  resultSet.close();
} catch (err) {
  console.error(`Query failed. Code:${err.code}, message:${err.message}`);
}

更新数据(Update)

let updateValues: ValuesBucket = {
  'AGE': 26,
  'SCORE': 95
};
let updatePredicates = new relationalStore.RdbPredicates('USER');
updatePredicates.equalTo('NAME', '张三');
try {
  let rowsUpdated = await rdbStore.update(updateValues, updatePredicates);
  console.info(`Update succeeded, updated rows: ${rowsUpdated}`);
} catch (err) {
  console.error(`Update failed. Code:${err.code}, message:${err.message}`);
}

删除数据(Delete)

let deletePredicates = new relationalStore.RdbPredicates('USER');
deletePredicates.equalTo('NAME', '张三');
try {
  let rowsDeleted = await rdbStore.delete(deletePredicates);
  console.info(`Delete succeeded, deleted rows: ${rowsDeleted}`);
} catch (err) {
  console.error(`Delete failed. Code:${err.code}, message:${err.message}`);
}

3. 数据库版本升级与字段迁移

如初始化代码所示,在RdbOpenCallbackonUpgrade方法中处理版本升级。通过比较oldVersionnewVersion,使用ALTER TABLE语句执行字段添加、修改或删除。对于复杂的迁移(如修改字段类型、拆分表),可能需要创建新表、迁移数据后删除旧表。

关键点

  • RdbStoreConfig中通过version字段指定数据库版本号。
  • onUpgrade方法在数据库版本号增加时自动触发。
  • 字段迁移操作应包裹在事务中以保证数据一致性。

总结

HarmonyOS Next的RDB提供了完整的关系型数据库操作能力,通过RdbStore API进行初始化、建表、增删改查。版本升级和字段迁移逻辑在RdbOpenCallback.onUpgrade中实现,需谨慎处理以保障数据完整性。

回到顶部