鸿蒙轻松背单词应用开发实战(六)-数据持久化与状态管理

前言

数据持久化和状态管理是应用开发的核心技术。本文详细介绍轻松背单词应用的数据存储方案和状态管理实现。

为什么需要数据持久化?

  1. 数据保存:保存用户学习进度
  2. 离线使用:支持离线学习
  3. 数据同步:多设备数据同步
  4. 性能优化:减少网络请求

数据持久化流程

数据生成

数据验证

数据存储

数据索引

数据读取

数据有效?

使用数据

数据恢复

一、Preferences数据存储

1.1 Preferences工具类

import preferences from '@ohos.data.preferences';

export class PreferencesUtil {
  private static instance: PreferencesUtil;
  private preferences: preferences.Preferences | null = null;
  
  static getInstance(): PreferencesUtil {
    if (!PreferencesUtil.instance) {
      PreferencesUtil.instance = new PreferencesUtil();
    }
    return PreferencesUtil.instance;
  }
  
  async init(context: Context): Promise<void> {
    try {
      this.preferences = await preferences.getPreferences(context, 'WordStudyStore');
    } catch (error) {
      console.error('Preferences init failed:', error);
    }
  }
  
  async put(key: string, value: string | number | boolean): Promise<void> {
    if (!this.preferences) return;
    await this.preferences.put(key, value);
    await this.preferences.flush();
  }
  
  async get(key: string, defaultValue: string | number | boolean): Promise<string | number | boolean> {
    if (!this.preferences) return defaultValue;
    return await this.preferences.get(key, defaultValue);
  }
}

1.2 用户设置存储

export class UserSettings {
  private preferences: PreferencesUtil = PreferencesUtil.getInstance();
  
  async saveDailyGoal(goal: number): Promise<void> {
    await this.preferences.put('daily_goal', goal);
  }
  
  async getDailyGoal(): Promise<number> {
    return await this.preferences.get('daily_goal', 20) as number;
  }
  
  async saveSoundEnabled(enabled: boolean): Promise<void> {
    await this.preferences.put('sound_enabled', enabled);
  }
  
  async getSoundEnabled(): Promise<boolean> {
    return await this.preferences.get('sound_enabled', true) as boolean;
  }
}

二、关系型数据库存储

2.1 数据库管理类

import relationalStore from '@ohos.data.relationalStore';

export class DatabaseManager {
  private static instance: DatabaseManager;
  private rdbStore: relationalStore.RdbStore | null = null;
  
  static getInstance(): DatabaseManager {
    if (!DatabaseManager.instance) {
      DatabaseManager.instance = new DatabaseManager();
    }
    return DatabaseManager.instance;
  }
  
  async init(context: Context): Promise<void> {
    const config: relationalStore.StoreConfig = {
      name: 'WordStudy.db',
      securityLevel: relationalStore.SecurityLevel.S1
    };
    
    this.rdbStore = await relationalStore.getRdbStore(context, config);
    await this.createTables();
  }
  
  private async createTables(): Promise<void> {
    const createWordTable = `
      CREATE TABLE IF NOT EXISTS words (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        word TEXT NOT NULL,
        translation TEXT NOT NULL,
        book_id INTEGER,
        create_time INTEGER
      )
    `;
    
    await this.rdbStore?.executeSql(createWordTable);
  }
}

2.2 数据访问对象

export class WordDAO {
  private dbManager: DatabaseManager = DatabaseManager.getInstance();
  
  async insertWord(word: WordModel): Promise<number> {
    const rdbStore = this.dbManager.getRdbStore();
    if (!rdbStore) return -1;
    
    const valueBucket = {
      word: word.word,
      translation: word.translation,
      book_id: word.bookId,
      create_time: Date.now()
    };
    
    return await rdbStore.insert('words', valueBucket);
  }
  
  async queryWordsByBook(bookId: number): Promise<WordModel[]> {
    const rdbStore = this.dbManager.getRdbStore();
    if (!rdbStore) return [];
    
    const predicates = new relationalStore.RdbPredicates('words');
    predicates.equalTo('book_id', bookId);
    
    const resultSet = await rdbStore.query(predicates);
    const words: WordModel[] = [];
    
    while (resultSet.goToNextRow()) {
      const word = new WordModel();
      word.id = resultSet.getLong(resultSet.getColumnIndex('id'));
      word.word = resultSet.getString(resultSet.getColumnIndex('word'));
      word.translation = resultSet.getString(resultSet.getColumnIndex('translation'));
      words.push(word);
    }
    
    resultSet.close();
    return words;
  }
}

2.3 数据库操作流程

存储引擎 数据库 数据访问对象 应用 存储引擎 数据库 数据访问对象 应用 插入单词数据 构建数据桶 insert(table, values) 写入数据 返回行ID 返回结果 返回插入结果

三、状态管理

3.1 全局状态管理

export class AppStateManager {
  private static instance: AppStateManager;
  private currentBook: WordBook | null = null;
  private studyProgress: Map<number, StudyProgress> = new Map();
  private listeners: Map<string, Set<Function>> = new Map();
  
  static getInstance(): AppStateManager {
    if (!AppStateManager.instance) {
      AppStateManager.instance = new AppStateManager();
    }
    return AppStateManager.instance;
  }
  
  setCurrentBook(book: WordBook): void {
    this.currentBook = book;
    this.notifyListeners('currentBook', book);
  }
  
  updateStudyProgress(wordId: number, progress: StudyProgress): void {
    this.studyProgress.set(wordId, progress);
    this.notifyListeners('studyProgress', { wordId, progress });
  }
  
  addListener(event: string, callback: Function): void {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, new Set());
    }
    this.listeners.get(event)!.add(callback);
  }
  
  private notifyListeners(event: string, data: any): void {
    const callbacks = this.listeners.get(event);
    if (callbacks) {
      callbacks.forEach(callback => callback(data));
    }
  }
}

3.2 组件状态管理

@Entry
@Component
struct StudyPage {
  @State currentWord: WordModel | null = null;
  @State showAnswer: boolean = false;
  @Provide('studyProgress') studyProgress: Map<number, StudyProgress> = new Map();
  
  private stateManager: AppStateManager = AppStateManager.getInstance();
  
  aboutToAppear() {
    this.stateManager.addListener('currentBook', (book: WordBook) => {
      if (book.words.length > 0) {
        this.currentWord = book.words[0];
      }
    });
  }
  
  build() {
    Column() {
      if (this.currentWord) {
        this.WordCard(this.currentWord);
      }
    }
    .width('100%')
    .height('100%');
  }
}

3.3 状态流转图

开始加载

加载成功

加载失败

开始学习

暂停学习

继续学习

学习完成

重新开始

初始状态

加载中

数据就绪

错误状态

学习中

暂停状态

完成状态

四、数据同步

4.1 数据同步管理

export class DataSyncManager {
  private static instance: DataSyncManager;
  private isSyncing: boolean = false;
  
  static getInstance(): DataSyncManager {
    if (!DataSyncManager.instance) {
      DataSyncManager.instance = new DataSyncManager();
    }
    return DataSyncManager.instance;
  }
  
  async startSync(): Promise<void> {
    if (this.isSyncing) return;
    this.isSyncing = true;
    
    try {
      await this.uploadLocalData();
      await this.downloadRemoteData();
      await this.mergeData();
    } catch (error) {
      console.error('Data sync failed:', error);
    } finally {
      this.isSyncing = false;
    }
  }
}

4.2 数据同步流程

有网络

无网络

开始同步

检查网络

上传本地数据

等待网络

下载远程数据

合并数据

冲突?

解决冲突

保存数据

同步完成

五、数据备份与恢复

5.1 数据备份

export class DataBackup {
  async exportData(): Promise<string> {
    const data = {
      version: '1.0',
      timestamp: Date.now(),
      books: await this.exportBooks(),
      words: await this.exportWords(),
      records: await this.exportRecords()
    };
    
    return JSON.stringify(data, null, 2);
  }
  
  async saveToFile(content: string): Promise<string> {
    const fileName = `word_study_backup_${Date.now()}.json`;
    const filePath = `${context.filesDir}/${fileName}`;
    
    const file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.WRITE_ONLY);
    fs.writeSync(file.fd, content);
    fs.closeSync(file);
    
    return filePath;
  }
}

5.2 数据恢复

export class DataRestore {
  async importData(jsonContent: string): Promise<boolean> {
    try {
      const data = JSON.parse(jsonContent);
      
      if (!this.validateData(data)) {
        return false;
      }
      
      await this.clearAllData();
      await this.importBooks(data.books);
      await this.importWords(data.words);
      await this.importRecords(data.records);
      
      return true;
    } catch (error) {
      console.error('Import data failed:', error);
      return false;
    }
  }
}

六、缓存管理

6.1 内存缓存

export class MemoryCache {
  private static instance: MemoryCache;
  private cache: Map<string, CacheItem> = new Map();
  private maxSize: number = 100;
  
  static getInstance(): MemoryCache {
    if (!MemoryCache.instance) {
      MemoryCache.instance = new MemoryCache();
    }
    return MemoryCache.instance;
  }
  
  set(key: string, value: any, ttl: number = 1800000): void {
    if (this.cache.size >= this.maxSize) {
      this.evictOldest();
    }
    
    this.cache.set(key, {
      value,
      expireTime: Date.now() + ttl,
      createTime: Date.now()
    });
  }
  
  get(key: string): any | null {
    const item = this.cache.get(key);
    
    if (!item || Date.now() > item.expireTime) {
      this.cache.delete(key);
      return null;
    }
    
    return item.value;
  }
}

七、总结

本文详细介绍了数据持久化与状态管理的实现。通过Preferences、关系型数据库、状态管理器和缓存机制,实现了高效可靠的数据管理。

核心要点

  1. 数据存储:Preferences用于简单数据,关系型数据库用于复杂数据
  2. 状态管理:全局状态管理和组件状态管理相结合
  3. 数据同步:支持多设备数据同步
  4. 缓存优化:内存缓存提高访问效率

系列文章导航:
下期预告: 鸿蒙轻松背单词应用开发实战(七)-应用测试与性能优化

Logo

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

更多推荐