鸿蒙 ArkTS 数据持久化技术详解

825 阅读3分钟

鸿蒙 ArkTS 数据持久化技术详解


一、PersistentStorage(持久化状态管理)

  • 用途:将 AppStorage 中的状态持久化到磁盘,适合保存简单应用配置(如主题、语言)。

  • 核心特性

    • 与 AppStorage 联动:通过 PersistentStorage.PersistProp 声明需持久化的属性。
    • 数据类型限制:仅支持 numberstringbooleanenum;对象需转为 JSON 字符串。
    • 轻量级:建议存储数据量 ≤2KB。
  • 代码示例

    // 初始化(需在应用启动时调用)  
    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)

  • 用途:存储轻量级键值数据(用户偏好设置、应用配置)。

  • 核心特性

    • 键值对存储:支持 numberstringboolean 及其数组类型。
    • 同步/异步 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();  
      

五、技术选型决策树

  1. 数据是否需要跨设备同步?

    • → 键值型数据库(分布式数据管理)。
    • → 进入下一步。
  2. 数据结构是否复杂?

    • → 关系型数据库(RDB)。
    • → 进入下一步。
  3. 是否需要全局高频访问?

    • → 用户首选项(Preferences)。
    • → 进入下一步。
  4. 是否需与 UI 状态绑定?

    • → PersistentStorage + AppStorage。
    • → 文件存储(大文件)或 Preferences(小数据)。

六、高频面试题

  1. PersistentStorage 能否直接存储对象?

    • :不能,需转为 JSON 字符串,读取时解析。
  2. RDB 如何优化复杂查询性能?

    • :添加索引、使用事务批处理、避免全表扫描。
  3. 键值型数据库冲突解决策略?

    • :默认时间戳覆盖,可自定义逻辑(如版本号校验)。

七、官方文档参考


总结

  • 简单配置:PersistentStorage(绑定状态) 或 用户首选项(全局键值)。
  • 跨设备同步:键值型数据库(分布式 KVStore)。
  • 复杂数据:关系型数据库(RDB + SQL)。
  • 大文件:文件存储(流式读写)。