在鸿蒙(HarmonyOS)开发中,集成并封装 SQLite 数据库主要有两种主流路径:一是直接使用官方提供的 RelationalStore(关系型数据库)API;二是通过 NAPI 机制在 C++ 层调用原生的 sqlite3 库。以下是这两种方案的详细集成与封装指南:

方案一:基于官方 RelationalStore 封装(推荐)

这是鸿蒙官方推荐的方式,底层基于 SQLite,但提供了更安全、类型友好的 ArkTS 接口。

1. 核心架构设计
为了避免在业务代码中散落大量数据库操作,建议封装一个通用的 RdbManager 工具类:

  • 单例模式:确保全局只有一个数据库连接实例,避免多表操作时频繁创建 RelationalStore 实例带来的资源开销。
  • 统一异常处理:在内部封装 try-catch,对外暴露清晰的 Promise 接口。

2. 基础 CRUD 封装

  • 获取实例:通过 relationalStore.getRdbStore(context, config) 获取 RdbStore 实例。
  • 增/改:使用 ValuesBucket(键值对容器)封装数据,结合 insert 和 update 方法进行操作。
  • 删/查:使用 RdbPredicates 构建类型安全的查询条件。查询返回的 ResultSet 结果集在使用完毕后,必须调用 close() 关闭,否则会导致数据库连接池耗尽。

3. 性能优化关键点

  • 批量插入:使用 batchInsert 接口一次性插入多条数据,大幅减少系统调用开销。
  • 事务管理:对于批量写入或高并发场景,强烈建议使用 createTransaction 包裹操作。实测表明,使用事务的性能比非事务高出约 200 倍,且能保证操作的原子性。

方案二:基于 NAPI + C++ 原生 sqlite3 封装

如果项目对性能有极致要求,或者需要复用现有的 C++ 数据库逻辑,可以通过 NAPI 机制在 Native 层操作数据库。

1. 架构分层

  • ArkTS UI层:负责界面展示,通过 import testNapi from 'libentry.so' 调用 Native 方法。
  • NAPI 绑定层:处理 ArkTS 与 C++ 之间的数据类型转换。
  • C++ 数据库操作层:直接调用 OH_Rdb API 或原生 sqlite3 接口执行 SQL。

2. 核心操作流程

  • 初始化:在 C++ 侧使用 OH_Rdb_GetOrOpen 打开或创建数据库,配置安全级别和存储路径。
  • 数据操作
    • 插入:通过 OH_Rdb_CreateValuesBucket 创建值桶,填充数据后调用 OH_Rdb_Insert
    • 查询:调用 OH_Rdb_Query 获取结果,并使用 OH_Cursor 遍历数据。
  • 内存管理:在 C++ 层操作完毕后,务必调用 destroy 释放 valueBucket 等资源,防止内存泄漏。

方案三:引入社区三方库(快捷方案)

如果不想从零封装,可以直接通过 OHPM 引入社区成熟的封装库:

  • @abner/datastore:支持通过对象形式(而非纯 SQL)创建表和执行增删改查,极大弱化了 SQL 拼接的复杂度,适合快速开发。
  • 自研 ORM 框架:部分开发者基于 @ohos/sqlite 封装了类似 Java Bean 注解映射、链式调用(如 query().where().orderBy())的轻量级 DBHelper,从根本上杜绝 SQL 注入风险。

一、 官方 RelationalStore 架构:生命周期约束与内存安全

在 API 12 及以上版本中,RDB 进行了底层重构,企业级封装必须严格遵循新的生命周期与内存管理规范。

  1. 实例生命周期与防锁死:禁止全局单例长期持有 RdbStore。页面销毁或工具类释放时,必须调用 close(),否则会导致数据库文件持续锁定,引发多页面同时操作崩溃或无法删除文件的问题。
  2. ResultSet 内存泄漏防护:查询返回的 ResultSet 在使用完毕后(如 while(goToNextRow()) 循环结束)必须显式调用 close(),否则内存会持续占用。
  3. 防 SQL 注入的谓词构造器:严禁手写拼接字符串 SQL,必须统一使用 RdbPredicates 构建条件(如 equalTocontainsorderByDesc),从底层杜绝注入风险。
// 核心:安全的查询与资源释放
let predicates = new relationalStore.RdbPredicates("note");
predicates.equalTo("id", 1);
let resultSet = await rdbStore.query(predicates, ["title", "content"]);
try {
    while (resultSet.goToNextRow()) {
        // 业务处理...
    }
} finally {
    resultSet.close(); // 强制释放内存
}

二、 极致性能:事务批量写入与并发锁

对于大量结构化数据(如笔记、商品列表、本地缓存),单次插入的性能瓶颈极大。

  1. 事务原子操作:批量新增或删除必须包裹在 beginTransaction / commit / rollback 事务中。API 12 完善了事务机制,批量插入失败会自动回滚,且实测性能比非事务高出约 200 倍。
  2. 大数量查询分页优化:禁止一次性加载海量数据。通过 RdbPredicates.offset().limit() 实现分页读取,配合内存优化策略防止 UI 卡顿。

三、 高阶架构:分布式关系型数据库(数据同步)

鸿蒙的核心优势在于分布式能力。企业级应用可通过 RDB 实现多设备间的无缝数据流转(如账单、备忘录多端同步)。

  1. 分布式表设置:通过 setDistributedTables() 将本地表标记为分布式表。
  2. 跨设备数据推送:调用 rdbStore.sync(SyncMode.SYNC_MODE_PUSH, predicates) 将本地变更推送至组网内的其他设备。
  3. 订阅与拉取:通过 on('dataChange') 监听远端设备数据变化,结合 remoteQuery() 拉取最新数据,并通过 EventHub 通知本地 UI 刷新。

四、 跨平台与 PC 端生态:Node.js 移植与 ORM 框架

对于需要跨端复用的项目,鸿蒙提供了强大的生态兼容方案。

  1. Node.js sqlite3 移植:在鸿蒙 PC 端,可通过 ohos-npm-ports 适配版或 --build-from-source 强制源码编译,实现 Node.js 项目零代码改动迁移。需注意补齐 binutilsar 归档工具)以支持 C++ 编译链路。
  2. Flutter sqflite 鸿蒙化:Flutter 开发者可直接引入 OpenHarmony TPC 仓库的 sqflite 适配版,利用单例模式管理连接,实现跨平台 CRUD 逻辑复用。
  3. 轻量级 ORM 框架:引入 @ohos/sqlite-orm,通过 @Entity@Column 等装饰器实现实体类与表结构的自动映射,支持链式调用(query().where().orderBy()),极大降低维护成本。

五、 ArkTS 核心层:RdbManager 安全封装与事务批量操作

封装一个全局单例,内置异常处理与生命周期管理,提供类型安全的 CRUD 接口。

// RdbManager.ets
import { relationalStore } from '@kit.ArkData';

export class RdbManager {
  private rdbStore: relationalStore.RdbStore | null = null;

  // 1. 初始化并获取单例实例
  async init(context: Context): Promise<relationalStore.RdbStore> {
    if (this.rdbStore) return this.rdbStore;
    const config: relationalStore.StoreConfig = {
      name: 'my_database.db',
      securityLevel: relationalStore.SecurityLevel.S1
    };
    this.rdbStore = await relationalStore.getRdbStore(context, config);
    return this.rdbStore;
  }

  // 2. 极致性能:事务批量插入(性能提升约200倍)
  async batchInsert(tableName: string, buckets: relationalStore.ValuesBucket[]): Promise<number> {
    if (!this.rdbStore) throw new Error('RdbStore not initialized');
    let totalInserted = 0;
    try {
      // 开启事务
      await this.rdbStore.beginTransaction();
      for (const bucket of buckets) {
        const rowId = await this.rdbStore.insert(tableName, bucket);
        if (rowId !== -1) totalInserted++;
      }
      // 提交事务
      await this.rdbStore.commit();
    } catch (err) {
      // 异常回滚
      await this.rdbStore.rollback();
      throw err;
    }
    return totalInserted;
  }

  // 3. 内存安全:强制释放 ResultSet
  async queryAll(tableName: string): Promise<relationalStore.ValuesBucket[]> {
    const predicates = new relationalStore.RdbPredicates(tableName);
    const resultSet = await this.rdbStore!.query(predicates);
    const results: relationalStore.ValuesBucket[] = [];
    try {
      while (resultSet.goToNextRow()) {
        const bucket: relationalStore.ValuesBucket = {};
        for (let i = 0; i < resultSet.columnCount; i++) {
          bucket[resultSet.getColumnName(i)] = resultSet.getString(i);
        }
        results.push(bucket);
      }
    } finally {
      resultSet.close(); // 核心:防止内存泄漏
    }
    return results;
  }
}

六、 高阶架构:分布式数据同步(多端流转)

利用鸿蒙分布式能力,实现本地数据的跨设备推送与变更监听。

// DistributedSync.ets
export class DistributedSync {
  // 1. 将本地表标记为分布式表
  static async setupDistributedTables(store: relationalStore.RdbStore) {
    const tableNameList = ['notes', 'messages'];
    await store.setDistributedTables(tableNameList);
  }

  // 2. 监听远端设备数据变更,并触发本地 UI 刷新
  static subscribeRemoteChanges(store: relationalStore.RdbStore, onRefresh: () => void) {
    store.on('dataChange', relationalStore.SubscribeType.SUBSCRIBE_TYPE_REMOTE, (data) => {
      console.info('Received remote data change:', data);
      onRefresh(); // 通知 UI 层重新拉取数据
    });
  }

  // 3. 将本地数据主动推送给组网内的其他设备
  static async pushDataToDevice(store: relationalStore.RdbStore) {
    const predicates = new relationalStore.RdbPredicates('notes');
    predicates.inDevices(['device-id-001']); // 指定目标设备
    await store.sync(relationalStore.SyncMode.SYNC_MODE_PUSH, predicates);
  }
}

七、 Native 高性能层:NAPI + C++ 原生 SQLite 调用

针对海量数据解析或复杂计算,绕过 ArkTS 层,直接在 C++ 层操作数据库。

// native/src/main/cpp/db_helper.cpp
#include "napi/native_api.h"
#include "ohos/data/rdb_store.h"

using namespace OHOS::Rdb;

// C++ 侧高性能插入
static napi_value NativeInsert(napi_env env, napi_callback_info info) {
    // 1. 获取 C++ 层的 RdbStore 实例
    auto store = RdbStore::GetOrOpen("my_database.db");
    
    // 2. 创建值桶并填充数据
    auto valueBucket = ValuesBucket::Create();
    valueBucket->PutString("title", "Native Note");
    valueBucket->PutInt("content", 100);
    
    // 3. 执行插入
    int64_t rowId = -1;
    store->Insert("notes", *valueBucket, rowId);
    
    // 4. 核心:手动销毁资源,防止 C++ 内存泄漏
    valueBucket->Destroy();
    
    napi_value result;
    napi_create_int64(env, rowId, &result);
    return result;
}

八、 跨端 ORM 框架:声明式实体映射

引入 @ohos/sqlite-orm 等轻量级 ORM,通过装饰器实现 Java Bean 风格的数据库映射。

// NoteEntity.ets
import { Entity, Column, PrimaryGeneratedColumn } from '@ohos/sqlite-orm';

@Entity('notes')
export class NoteEntity {
  @PrimaryGeneratedColumn()
  id: number = 0;

  @Column({ type: 'varchar', length: 255 })
  title: string = '';

  @Column({ type: 'text' })
  content: string = '';

  @Column({ type: 'datetime', default: 'CURRENT_TIMESTAMP' })
  createTime: string = '';
}

// 业务层链式调用:彻底告别手写 SQL
const notes = await dbManager.query(NoteEntity)
  .where('title', 'like', '%鸿蒙%')
  .orderBy('createTime', 'DESC')
  .limit(10)
  .execute();
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐