鸿蒙 ArkTS 数据持久化技术详解
一、PersistentStorage(持久化状态管理)
-
用途:将 AppStorage 中的状态持久化到磁盘,适合保存简单应用配置(如主题、语言)。
-
核心特性:
- 与 AppStorage 联动:通过
PersistentStorage.PersistProp声明需持久化的属性。 - 数据类型限制:仅支持
number、string、boolean、enum;对象需转为 JSON 字符串。 - 轻量级:建议存储数据量 ≤2KB。
- 与 AppStorage 联动:通过
-
代码示例:
// 初始化(需在应用启动时调用) PersistentStorage.PersistProp('theme', 'light'); PersistentStorage.PersistProp('user', JSON.stringify({ name: 'Alice' })); // 通过 AppStorage 访问 let theme = AppStorage.get<string>('theme'); let user = JSON.parse(AppStorage.get<string>('user')); -
注意事项:
- 直接操作
AppStorage,无需访问PersistentStorage。 - 对象类型需手动序列化/反序列化。
- 直接操作
二、用户首选项(ohos.data.preferences)
-
用途:存储轻量级键值数据(用户偏好设置、应用配置)。
-
核心特性:
- 键值对存储:支持
number、string、boolean及其数组类型。 - 同步/异步 API:高频操作建议异步,主线程同步需谨慎。
- 全局作用域:数据全局可访问,适合高频读取场景。
- 键值对存储:支持
-
代码示例:
// 获取 Preferences 实例 let prefs = dataPreferences.getPreferencesSync(context, 'settings'); // 同步写入 prefs.putSync('volume', 80); prefs.flushSync(); // 同步读取 let volume = prefs.getSync('volume', 50); -
与 PersistentStorage 区别:
特性 用户首选项 PersistentStorage 数据类型 简单类型及数组 简单类型 + JSON 字符串 作用域 全局(跨组件) 全局(AppStorage 绑定) 加密支持 支持(S1-S4 安全级别) 无
三、键值型数据库(分布式数据管理)
-
用途:跨设备同步简单数据(同华为账号),如商品价格、员工考勤记录。
-
核心特性:
- 自动同步:网络恢复后自动同步,默认时间戳冲突策略。
- 高性能:读写速度快,支持批量操作。
- 容量限制:单条 ≤4MB,总量 ≤2GB。
-
代码示例:
// 创建 KVManager const kvManager = distributedKVStore.createKVManager({ bundleName: 'com.example.app', context: context }); // 获取 KVStore const kvStore = await kvManager.getKVStore('storeId', { kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION }); // 写入数据 await kvStore.putString('price', '99.9'); // 读取数据 let price = await kvStore.getString('price'); -
适用场景:
- 设备间同步用户购物车、待办事项。
- 存储无需复杂查询的键值数据。
四、关系型数据库(RDB)
-
用途:存储复杂结构化数据(订单、学生信息),支持 SQL 查询。
-
核心特性:
- 完整 SQL 支持:事务、索引、视图、联合查询。
- 数据加密:数据库文件加密存储(SecurityLevel.S1-S4)。
- 高性能事务:批量操作建议使用事务提升效率。
-
代码示例:
// 定义实体类 @Entity class Student { @PrimaryKey id: number; @ColumnInfo(name: 'name') name: string; @ColumnInfo(name: 'age') age: number; } // 创建数据库 const rdbStore = await relationalStore.getRdbStore(context, { name: 'school.db', securityLevel: relationalStore.SecurityLevel.S2 }); // 建表 await rdbStore.executeSql( 'CREATE TABLE IF NOT EXISTS student (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)' ); // 插入数据 const student = { id: 1, name: 'Alice', age: 20 }; await rdbStore.insert('student', student); // 查询数据 const predicates = new relationalStore.RdbPredicates('student'); predicates.equalTo('age', 20); let resultSet = await rdbStore.query(predicates, ['name']); -
优化技巧:
-
索引优化:为高频查询字段添加索引。
await rdbStore.executeSql('CREATE INDEX idx_age ON student (age)'); -
事务批处理:
await rdbStore.beginTransaction(); await rdbStore.insert('student', { id: 2, name: 'Bob', age: 22 }); await rdbStore.commit();
-
五、技术选型决策树
-
数据是否需要跨设备同步?
- 是 → 键值型数据库(分布式数据管理)。
- 否 → 进入下一步。
-
数据结构是否复杂?
- 是 → 关系型数据库(RDB)。
- 否 → 进入下一步。
-
是否需要全局高频访问?
- 是 → 用户首选项(Preferences)。
- 否 → 进入下一步。
-
是否需与 UI 状态绑定?
- 是 → PersistentStorage + AppStorage。
- 否 → 文件存储(大文件)或 Preferences(小数据)。
六、高频面试题
-
PersistentStorage 能否直接存储对象?
- 答:不能,需转为 JSON 字符串,读取时解析。
-
RDB 如何优化复杂查询性能?
- 答:添加索引、使用事务批处理、避免全表扫描。
-
键值型数据库冲突解决策略?
- 答:默认时间戳覆盖,可自定义逻辑(如版本号校验)。
七、官方文档参考
- PersistentStorage: HarmonyOS 文档
- 用户首选项: HarmonyOS Preferences
- RDB: HarmonyOS RDB
总结:
- 简单配置:PersistentStorage(绑定状态) 或 用户首选项(全局键值)。
- 跨设备同步:键值型数据库(分布式 KVStore)。
- 复杂数据:关系型数据库(RDB + SQL)。
- 大文件:文件存储(流式读写)。