👋 你好,欢迎来到我的博客!我是【菜鸟学鸿蒙】
   我是一名在路上的移动端开发者,正从传统“小码农”转向鸿蒙原生开发的进阶之旅。为了把学习过的知识沉淀下来,也为了和更多同路人互相启发,我决定把探索 HarmonyOS 的过程都记录在这里。
  
  🛠️ 主要方向:ArkTS 语言基础、HarmonyOS 原生应用(Stage 模型、UIAbility/ServiceAbility)、分布式能力与软总线、元服务/卡片、应用签名与上架、性能与内存优化、项目实战,以及 Android → 鸿蒙的迁移踩坑与复盘。
  🧭 内容节奏:从基础到实战——小示例拆解框架认知、专项优化手记、实战项目拆包、面试题思考与复盘,让每篇都有可落地的代码与方法论。
  💡 我相信:写作是把知识内化的过程,分享是让生态更繁荣的方式。
  
   如果你也想拥抱鸿蒙、热爱成长,欢迎关注我,一起交流进步!🚀

前言

数据库问题有一个很典型的调试困境:页面显示不对时,我们往往只能继续加日志——打印插入参数、打印 SQL、打印查询结果、打印更新后的对象。日志越来越多,但真正想确认的事情其实很简单:数据库里此刻到底存了什么?

DevEco Studio 的 Database Inspector 正是为这类场景准备的。官方文档明确说明,它可以直接连接运行中的应用数据库,在 IDE 中查看数据库和表数据,也可以执行 SQL 修改数据,不需要先把数据库导出到电脑。当前支持 SQLite 和向量数据库。该能力从 DevEco Studio 6.0.2 Beta1 开始提供。

本文不做复杂数据库封装,而是搭一个最小的 ArkTS 关系型数据库示例:创建一张任务表,通过应用按钮写入、更新数据,再用 Database Inspector 观察整个变化过程。重点不是数据库 API 本身,而是建立一套以后可以直接复用的数据库排查方法。

一、为什么数据库问题经常越查日志越多

假设应用维护一张任务表:

TASK
├── ID
├── TITLE
├── STATUS
└── UPDATED_AT

页面点击“新增任务”以后,业务代码执行了数据库写入;再点击“完成任务”,代码把 STATUS 从 0 更新为 1。

如果页面最终仍然显示“未完成”,问题可能出现在很多位置:

  • 数据根本没有插入;
  • 插入成功,但字段值和预期不同;
  • UPDATE 的 WHERE 条件没有命中;
  • 数据库已经变化,但页面状态没有重新加载;
  • 查询使用了错误的条件;
  • 调试时看的并不是当前应用实际使用的数据库。

只看 UI 很难区分这些情况。

传统方式只能在数据库调用前后不停打印日志。Database Inspector 改变的是排查入口:先直接确认持久化层当前状态,再判断问题应该继续往数据库层还是 UI/业务层查。

官方给出的典型使用场景也正是两类:应用操作导致数据库内容变化时实时检查结果,以及直接修改数据库数据以构造测试场景。

二、先把版本和限制弄清楚

如果文章以 HarmonyOS 7 为背景,这里有一个版本关系需要先说清楚。

华为官方的 26.0.0 升级适配文档明确指出,HarmonyOS 7.0 对应 26.0.0 版本,并建议应用升级开发套件并适配 26.0.0。

但 Database Inspector 并不是 API 26 才能使用。

官方目前的限制是:

项目官方约束
Database Inspector 引入版本DevEco Studio 6.0.2 Beta1 起
设备 API 22 及以上支持数据库查看和相应调试能力
设备低于 API 22SQLite 只支持查看,不支持修改
向量数据库低于 API 22 无法使用
release 签名应用不支持
数据库位置仅支持调试 database 目录下数据库
加密数据库不支持调试
隐私用户、多用户数据库不支持
数据库导入、导出Inspector 不支持
SQL 历史不支持
SQL 事务Inspector 的 SQL 执行不支持

这些限制均来自当前官方 Database Inspector 文档。

这里尤其要注意 release 签名、加密库和数据库目录三个条件。如果连接应用后左侧什么都没有,不应该第一反应就怀疑 RDB API。

三、搭一个最小关系型数据库场景

下面使用 ArkData 的关系型数据库能力创建 task_demo.db。

关系型数据库底层基于 SQLite,对外提供增删改查接口,也允许直接执行 SQL。华为当前官方示例使用:

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

并通过 relationalStore.getRdbStore() 获得 RdbStore。官方资料也给出了 StoreConfig、SecurityLevel.S1、executeSql()、insertSync()、querySqlSync() 等用法。

本文最小目标只有三个:

  1. 创建数据库和 TASK 表;
  2. 点击按钮插入一条任务;
  3. 点击另一个按钮修改任务状态。

这样 Database Inspector 中的数据变化会非常直观。

1. 数据库配置

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

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

const CREATE_TASK_TABLE: string = `
  CREATE TABLE IF NOT EXISTS TASK (
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    TITLE TEXT NOT NULL,
    STATUS INTEGER NOT NULL,
    UPDATED_AT INTEGER NOT NULL
  )
`;

这里保持最小配置,不加入数据库加密。这样既便于理解,也符合 Database Inspector 不支持调试加密数据库的官方限制。

华为官方关系型数据库示例同样通过 StoreConfig 指定数据库名称和 SecurityLevel.S1。

2. 打开数据库并建表

@Entry
@Component
struct Index {
  private context: common.UIAbilityContext =
    this.getUIContext().getHostContext() as common.UIAbilityContext;

  private store: relationalStore.RdbStore | undefined = undefined;

  aboutToAppear(): void {
    this.initDatabase();
  }

  async initDatabase(): Promise<void> {
    this.store = await relationalStore.getRdbStore(this.context, DB_CONFIG);
    await this.store.executeSql(CREATE_TASK_TABLE);
  }

  build() {
    Column({ space: 16 }) {
      Button('新增任务')
        .onClick(() => {
          this.addTask();
        })

      Button('完成任务 1')
        .onClick(() => {
          this.finishTask();
        })
    }
    .width('100%')
    .padding(24)
  }
}

官方示例确认了 getRdbStore() 获取数据库实例以及通过 executeSql() 创建数据库表的调用方式。

这段代码真正需要关注的是:数据库必须已经被应用打开并建立对应文件后,Inspector 才有实际对象可以连接和查看。

3. 写入一条数据

给组件增加下面的方法:

addTask(): void {
  if (!this.store) {
    return;
  }

  const values: relationalStore.ValuesBucket = {
    TITLE: '检查 Database Inspector',
    STATUS: 0,
    UPDATED_AT: Date.now()
  };

  this.store.insertSync('TASK', values);
}

ValuesBucket 是关系型数据库写入数据时使用的键值集合。官方文档定义它可以保存数据库字段对应的数据值;当前官方关系型数据库示例也直接通过 insertSync(table, valueBucket) 写入数据。

为了让调试重点更集中,这里没有在页面中查询并展示结果。

我们的目标就是:应用负责改数据库,Inspector 负责告诉我们数据库究竟变成了什么。

4. 修改业务状态

再加入一个更新操作:

async finishTask(): Promise<void> {
  if (!this.store) {
    return;
  }

  await this.store.executeSql(
    `UPDATE TASK
     SET STATUS = 1,
         UPDATED_AT = ${Date.now()}
     WHERE ID = 1`
  );
}

这里故意把逻辑保持得非常直接,让 Inspector 能够观察:

STATUS
0 -> 1

关系型数据库官方资料明确说明 RDB 可以直接执行开发者输入的 SQL;官方示例也使用 executeSql() 执行建表 SQL。

实际业务工程中仍应按照自身数据访问层设计组织 SQL、参数绑定和异常处理,本文代码只承担最小调试场景的职责。

四、打开 Database Inspector

应用运行并创建数据库以后,在 DevEco Studio 中进入:

View
  -> Tool Windows
    -> Database Inspector

这是官方文档给出的入口。

Inspector 打开以后,主要区域可以理解为四部分:

设备
应用包名
数据库 / 表
SQL 与数据查看区域

接下来:

  1. 从设备下拉框选择已经连接的设备;
  2. 选择正在调试的应用包名;
  3. 点击 Connect to Databases;
  4. 展开数据库节点找到 task_demo.db;
  5. 找到 TASK 表。

官方说明,当设备 API 低于 22 时,Inspector 会把 SQLite 数据库下载到本地再展示,因此界面看到的是本机路径;API 22 及以上则显示设备上的数据库路径。

五、先别执行 SQL,直接看表结构和数据

连接成功以后,双击 TASK 表。

Database Inspector 会在右侧展示表数据,官方当前默认按照 20 条/页显示。

此时回到应用点击一次“新增任务”。

理论上数据库会出现类似数据:

ID | TITLE                    | STATUS | UPDATED_AT
1  | 检查 Database Inspector   | 0      | ...

这里有一个非常关键的调试细节:

Inspector 的数据页面不会因为应用修改了数据库就自动刷新。

官方明确指出,无论是通过 SQL 修改数据,还是应用自身更新数据库,数据展示页都不会自动刷新,需要重新执行查询或者点击刷新按钮。

因此出现下面这种情况时:

“我按钮都点了,为什么 Inspector 还是原来的数据?”

先不要认定数据库写入失败。

点击 Refresh Table 再看。

这个细节很小,但如果不知道,很容易把“Inspector 还没刷新”错误判断成“业务代码没有写进去”。

六、HarmonyOS 7 / 26.0.0 下,SQL 编辑器更适合做现场验证

左侧点击 New Query 可以打开 SQL Editor。

先选择 task_demo.db,然后执行:

SELECT
  ID,
  TITLE,
  STATUS,
  UPDATED_AT
FROM TASK
ORDER BY ID;

这比在应用代码里临时增加一个查询接口更适合验证持久化结果。

从官方文档描述来看,26.0.0 开始,SQLite SQL 编辑器增加了:

  • SQL 语法高亮;
  • SQL 关键词自动联想;
  • 表字段自动联想补全。

更实用的是,多语句执行也从 26.0.0 开始得到支持。

例如可以写:

INSERT INTO TASK(TITLE, STATUS, UPDATED_AT)
VALUES('Inspector 创建的数据', 0, 100);

UPDATE TASK
SET STATUS = 1
WHERE TITLE = 'Inspector 创建的数据';

SELECT *
FROM TASK;

多条 SQL 使用分号分隔即可。

官方还支持选中一条或多条 SQL 后右键执行。

对于“这个 UPDATE 到底能不能命中”“查询条件到底对不对”这种问题,这种方式比修改 ArkTS、重新编译、安装、运行再看日志要直接得多。

但这里有一个边界不能忽略:Database Inspector 的 SQL 执行不支持事务,也不提供 SQL 历史记录。

所以不要把 Inspector 当成完整数据库客户端,它的定位仍然是开发调试工具。

七、API 26 还能直接改表格数据

从 26.0.0 开始,Database Inspector 还支持可视化修改 SQLite 表里的数据。

官方操作方式是:

双击单元格
→ 修改内容
→ Enter 或点击其他区域提交

不过支持范围有限,只支持字符串、数值、布尔等常规基础数据类型,二进制数据类型不支持可视化修改。

例如,可以直接把:

STATUS = 0

改成:

STATUS = 1

然后回到应用触发自己的重新查询逻辑。

这特别适合验证一个问题:

页面异常究竟来自数据库中的值,还是来自页面读取和状态同步逻辑?

如果手动把数据库改成预期值以后,页面经过业务重新读取仍然显示错误,就可以把排查重点转向数据读取、状态管理或 UI 层。

反过来,如果修改数据库后页面行为恢复正常,就应该继续追写入流程。

这就是 Inspector 比不断增加日志更有价值的地方:它能把问题快速切层。

八、修改业务以后,怎么观察数据变化

现在回到示例应用:

点击“新增任务”
→ Inspector 刷新
→ STATUS = 0

点击“完成任务 1”
→ Inspector 再刷新
→ STATUS = 1

不要只盯 STATUS。

还可以一起观察:

ID 是否符合预期
TITLE 有没有被错误覆盖
UPDATED_AT 是否发生变化
记录数量有没有异常增加

假设点击一次“新增任务”,Inspector 刷新以后突然出现两条完全相同的数据,那么就不必再从页面渲染开始查了。

数据库已经直接证明:

写入动作发生了两次

接下来应该检查按钮事件、生命周期初始化、重复订阅或者数据访问层调用路径。

如果数据库只有一条,而页面出现两条,则应该继续向 UI 数据源方向排查。

这种“先确定哪一层正确”的方法,比单纯增加日志更稳定。

九、几个容易理解错的地方

1. Inspector 看到的不是自动实时刷新的数据

“连接的是运行中的数据库”和“表格自动实时刷新”是两回事。

官方明确要求数据变化以后重新查询或点击刷新。

所以调试动作最好形成固定顺序:

执行应用操作
→ Refresh Table
→ 查看实际数据

2. API 26 不是 Database Inspector 的最低版本

设备 API 22 才是当前完整调试能力的重要门槛。

26.0.0 带来的是 SQL 编辑器、多语句执行、自动补全和表格可视化修改等增强。

不要把两者混在一起。

3. 加密数据库看不了

这不是连接失败,而是官方明确写出的不支持场景。

如果实际工程启用了关系型数据库加密,为了使用 Inspector 调试,官方建议使用非加密数据库进行调试。

当然,这只能用于开发调试环境,不能因此改变正式版本的数据安全设计。

4. release 签名应用不能这样调

官方明确说明 Database Inspector 不支持使用 release 签名的应用。

因此如果同一套代码 Debug 构建可以连接,换成 release 签名后无法连接,不应该继续从数据库 API 本身找原因。

5. 只支持 database 目录内数据库

Inspector 当前仅支持调试 database 目录下数据库。

关系型数据库官方资料同时说明,如果 StoreConfig 不指定 rootDir,数据库默认会建立在应用 databaseDir 下相应 RDB 路径;而指定 rootDir 的使用方式还有自己的只读等约束。

如果工程自己处理了特殊数据库文件路径,这一点要先确认。

十、数据库问题可以按这个顺序排查

以后遇到“数据明显不对”的问题,可以先按下面顺序走一遍:

1. 确认当前运行的是可调试构建,而不是 release 签名版本
          ↓
2. 确认目标数据库不是加密数据库
          ↓
3. 确认数据库位于 Inspector 支持的 database 目录
          ↓
4. 连接设备和正确的应用包名
          ↓
5. 展开数据库并查看实际表结构
          ↓
6. 执行业务操作
          ↓
7. Refresh Table
          ↓
8. 判断数据是否真的发生预期变化
          ↓
9. 用 SQL Editor 独立验证查询或更新条件
          ↓
10. 再判断问题属于数据库层、业务状态层还是 UI 层

如果 SQL 本身执行异常,还可以进一步结合 ArkData 提供的诊断能力。

华为 ArkData FAQ 明确提供了 sqliteErrorOccurred 事件用于获取 SQL 执行异常信息,也提供 getInsertSqlInfo、getUpdateSqlInfo、getDeleteSqlInfo、getQuerySqlInfo 等接口查看关系型数据库生成的 SQL。

也就是说,Database Inspector 并不是取代所有日志。

更合理的分工是:

Inspector:
确认数据库当前真实状态

SQL Editor:
快速验证 SQL 与数据

ArkData 错误信息:
定位执行异常

业务日志:
追调用链和业务状态

这样日志会少很多,而且每类工具解决的问题更明确。

十一、官方明确不支持的场景,别继续和工具较劲

最后把当前官方限制单独收一下。

遇到下面情况,Database Inspector 本身就不是合适的调试手段:

  • release 签名应用;
  • 加密数据库;
  • 隐私用户数据库;
  • 多用户数据库;
  • database 目录之外的数据库;
  • 需要通过 Inspector 导入或导出数据库;
  • 希望使用 SQL 历史;
  • 希望直接在 Inspector SQL 执行器中组织事务。

另外,API 22 以下设备的 SQLite 只能查看、不能修改,向量数据库则无法使用。

这些条件最好在调试开始前就确认,而不是连接失败以后反复重启 IDE、重装应用或者怀疑数据库损坏。

开发经验总结

Database Inspector 最有价值的地方,并不是“IDE 里多了一个 SQLite 查看器”,而是它改变了数据库问题的排查顺序。

过去可能是:

发现页面异常
→ 猜数据库
→ 加日志
→ 再运行
→ 再加日志

现在可以变成:

发现页面异常
→ 直接看数据库真实状态
→ SQL 验证
→ 判断问题层级
→ 再补必要日志

这篇文章里真正建议记住的是四点:

第一,先分清版本。 HarmonyOS 7 对应 26.0.0,但 Database Inspector 的设备使用门槛不能简单写成 API 26。

第二,数据变了记得刷新。 应用写入数据库后 Inspector 页面不会自动更新。

第三,API 26 下可以充分利用 SQL 编辑器。 多语句执行、语法高亮和自动联想让临时验证 SQL 更方便。

第四,先看支持边界。 release 签名、加密库、多用户等场景官方已经明确不支持,遇到这些条件就应该换调试方法。

如果正在排查一个“数据库好像没更新”的问题,可以先做一个很简单的动作:打开 Database Inspector,在触发业务操作前后分别刷新一次目标表。很多时候,这一步就足以判断下一步究竟应该继续追数据库,还是转去检查业务状态和页面逻辑。

📝 写在最后

如果你觉得这篇文章对你有帮助,或者有任何想法、建议,欢迎在评论区留言交流!你的每一个点赞 👍、收藏 ⭐、关注 ❤️,都是我持续更新的最大动力!

我是一个在代码世界里不断摸索的小码农,愿我们都能在成长的路上越走越远,越学越强!

感谢你的阅读,我们下篇文章再见~👋

✍️ 作者:菜鸟不学编程
🧵 本文原创,转载请注明出处。

Logo

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

更多推荐