基于HarmonyOS的情侣美食管理应用开发实战(五)- 数据持久化问题修复
·
基于HarmonyOS的情侣美食管理应用开发实战(五)- 数据持久化问题修复
📖 系列文章目录
- (一)项目设计与角色管理
- (二)菜谱管理与订单系统
- (三)美食相册与设置功能
- (四)数据库优化与问题解决
- (五)数据持久化问题修复(本文)
- (六)图片显示问题修复
一、问题发现
1.1 问题现象
在测试情侣美食管理应用时,发现了一个严重的问题:
用户操作流程:
- 打开应用,添加菜谱"凉拌猪耳朵"
- 填写菜谱信息,上传图片
- 保存成功,菜谱出现在列表中
- 关闭应用(完全退出)
- 重新打开应用
预期结果:
- 菜谱"凉拌猪耳朵"应该还在列表中
- 图片应该正常显示
实际结果:
- ❌ 菜谱列表为空
- ❌ 所有数据丢失
- ❌ 需要重新添加菜谱

1.2 问题影响
这个问题严重影响应用的使用价值:
- 用户辛苦添加的菜谱无法保存
- 无法积累菜谱库
- 应用失去了实际意义
二、问题定位
2.1 初步排查
首先检查数据库相关代码,查看 RdbUtil.ets 的初始化方法:
static async init(context: Context): Promise<void> {
LogUtil.info(RdbUtil.TAG, '开始初始化数据库')
// 删除旧数据库强制重建(开发阶段)
try {
await relationalStore.deleteRdbStore(context, CommonConstant.DB_NAME)
LogUtil.info(RdbUtil.TAG, '已删除旧数据库,将重新创建')
} catch (err) {
LogUtil.info(RdbUtil.TAG, '数据库不存在或删除失败,继续创建新数据库')
}
// 创建数据库配置
const config: relationalStore.StoreConfig = {
name: CommonConstant.DB_NAME,
securityLevel: relationalStore.SecurityLevel.S1
}
// 创建数据库
RdbUtil.rdbStore = await relationalStore.getRdbStore(context, config)
// 创建表结构
await RdbUtil.createTables()
LogUtil.info(RdbUtil.TAG, '数据库初始化完成')
}
2.2 问题分析
发现问题:
代码中有一段删除数据库的逻辑:
await relationalStore.deleteRdbStore(context, CommonConstant.DB_NAME)
问题原因:
-
开发阶段的遗留代码
- 开发时为了快速迭代,每次都删除旧数据库
- 便于测试表结构变更
-
忘记移除
- 发布时忘记移除这段代码
- 导致每次启动都会删除数据库
-
执行流程
- 应用启动 →
RdbUtil.init() - 删除旧数据库 → 所有数据丢失
- 创建新数据库 → 空数据库
- 结果:数据无法持久化
- 应用启动 →
三、解决方案
3.1 修复代码
移除删除数据库的逻辑,直接使用 getRdbStore:
static async init(context: Context): Promise<void> {
LogUtil.info(RdbUtil.TAG, '开始初始化数据库')
// 数据库配置
const config: relationalStore.StoreConfig = {
name: CommonConstant.DB_NAME,
securityLevel: relationalStore.SecurityLevel.S1
}
// 获取数据库实例(如果不存在会自动创建)
RdbUtil.rdbStore = await relationalStore.getRdbStore(context, config)
// 创建表结构
await RdbUtil.createTables()
LogUtil.info(RdbUtil.TAG, '数据库初始化完成')
}
3.2 关键改动
改动说明:
- ✅ 移除了
deleteRdbStore的调用 - ✅ 直接使用
getRdbStore获取数据库实例 - ✅ 系统会自动判断数据库是否存在
- ✅ 不存在则创建,存在则打开
API说明:
// getRdbStore 的行为:
// - 如果数据库不存在,自动创建并返回
// - 如果数据库已存在,直接打开并返回
// - 不会删除已有数据
3.3 数据库文件位置
数据库文件保存在应用私有目录:
/data/app/el2/100/database/com.example.menurecipe/rdb/MenuRecipe.db
特点:
- 应用私有目录,其他应用无法访问
- 应用卸载时会被清除
- 应用更新时数据保留
四、验证测试
4.1 测试步骤
第一次测试:
- 启动应用
- 添加菜谱"凉拌猪耳朵"
- 查看菜谱列表,确认菜谱在

第二次测试: - 完全关闭应用(从后台清除)
- 重新打开应用
- 查看菜谱列表

4.2 测试结果
修复前:
- ❌ 重启后菜谱列表为空
- ❌ 数据库文件被删除重建
修复后:
- ✅ 重启后菜谱列表正常显示
- ✅ 3个菜谱都在列表中
- ✅ 图片路径正确保存
- ✅ 数据库文件保留
4.3 日志验证
查看应用日志:
[INFO] RdbUtil: 开始初始化数据库
[INFO] RdbUtil: 数据库初始化完成
说明:
- 没有出现"已删除旧数据库"的日志
- 数据库直接打开,没有重建
五、最佳实践
5.1 数据库初始化建议
开发阶段:
// 可以使用环境变量控制
if (BuildConfig.DEBUG) {
// 仅在调试模式删除数据库
try {
await relationalStore.deleteRdbStore(context, DB_NAME)
LogUtil.info(TAG, 'DEBUG模式:删除旧数据库')
} catch (err) {
// 忽略错误
}
}
发布阶段:
- 必须移除删除数据库的逻辑
- 确保数据能够持久化
- 考虑数据库版本管理
5.2 数据库版本管理
如果需要修改表结构,应该使用版本管理:
// 检查数据库版本
const version = await this.getVersion()
if (version < 2) {
// 升级到版本2
await this.upgradeToV2()
}
if (version < 3) {
// 升级到版本3
await this.upgradeToV3()
}
优点:
- 保留用户数据
- 平滑升级
- 避免数据丢失
六、总结
本篇文章解决了数据持久化问题:
问题原因:
- 开发阶段的删除数据库代码没有移除
- 每次启动都会重建数据库
解决方案:
- 移除
deleteRdbStore调用 - 使用
getRdbStore自动创建或打开数据库
修复效果:
- ✅ 菜谱数据能够持久保存
- ✅ 重启后数据不丢失
- ✅ 应用真正具备了实用价值
这个问题提醒我们:开发阶段的临时代码,一定要在发布前仔细检查和清理,否则可能带来严重的后果。
更多推荐

所有评论(0)