鸿蒙多功能工具箱开发实战(十八)-数据持久化存储实现

前言

数据持久化是应用开发的重要环节。本文将讲解HarmonyOS中的数据存储方案,包括Preferences轻量级存储和关系型数据库的使用。

一、Preferences轻量级存储

1.1 Preferences概述

Preferences适用于存储少量数据,如用户设置、应用配置等。

1.2 封装Preferences服务

import preferences from '@ohos.data.preferences'

export class PreferencesService {
  private static instance: PreferencesService
  private preferences: preferences.Preferences

  private constructor() {}

  static async getInstance(): Promise<PreferencesService> {
    if (!PreferencesService.instance) {
      const service = new PreferencesService()
      service.preferences = await preferences.getPreferences(
        globalThis.context,
        'toolbox_prefs'
      )
      PreferencesService.instance = service
    }
    return PreferencesService.instance
  }

  /**
   * 保存数据
   */
  async put(key: string, value: string | number | boolean): Promise<void> {
    await this.preferences.put(key, value)
    await this.preferences.flush()
  }

  /**
   * 获取数据
   */
  async get(key: string, defaultValue: string | number | boolean): Promise<string | number | boolean> {
    return await this.preferences.get(key, defaultValue)
  }

  /**
   * 删除数据
   */
  async delete(key: string): Promise<void> {
    await this.preferences.delete(key)
    await this.preferences.flush()
  }

  /**
   * 清空所有数据
   */
  async clear(): Promise<void> {
    await this.preferences.clear()
    await this.preferences.flush()
  }
}

1.3 使用示例

// 保存用户设置
const prefs = await PreferencesService.getInstance()
await prefs.put('theme', 'dark')
await prefs.put('fontSize', 16)
await prefs.put('notification', true)

// 读取用户设置
const theme = await prefs.get('theme', 'light')
const fontSize = await prefs.get('fontSize', 14)

二、关系型数据库

2.1 数据库封装

import relationalStore from '@ohos.data.relationalStore'

export class DatabaseService {
  private static instance: DatabaseService
  private rdbStore: relationalStore.RdbStore

  private constructor() {}

  static async getInstance(): Promise<DatabaseService> {
    if (!DatabaseService.instance) {
      const service = new DatabaseService()
      service.rdbStore = await relationalStore.getRdbStore(
        globalThis.context,
        {
          name: 'toolbox.db',
          securityLevel: relationalStore.SecurityLevel.S1
        }
      )
      await service.createTables()
      DatabaseService.instance = service
    }
    return DatabaseService.instance
  }

  /**
   * 创建表
   */
  private async createTables(): Promise<void> {
    const sql = `
      CREATE TABLE IF NOT EXISTS history (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        tool_name TEXT NOT NULL,
        params TEXT,
        result TEXT,
        create_time INTEGER
      )
    `
    await this.rdbStore.executeSql(sql)
  }

  /**
   * 插入数据
   */
  async insert(table: string, values: relationalStore.ValuesBucket): Promise<number> {
    return await this.rdbStore.insert(table, values)
  }

  /**
   * 查询数据
   */
  async query(sql: string, args?: Array<relationalStore.ValueType>): Promise<relationalStore.ResultSet> {
    return await this.rdbStore.querySql(sql, args)
  }

  /**
   * 更新数据
   */
  async update(
    table: string,
    values: relationalStore.ValuesBucket,
    predicates: relationalStore.RdbPredicates
  ): Promise<number> {
    return await this.rdbStore.update(values, predicates)
  }

  /**
   * 删除数据
   */
  async delete(predicates: relationalStore.RdbPredicates): Promise<number> {
    return await this.rdbStore.delete(predicates)
  }
}

2.2 历史记录管理

export interface HistoryRecord {
  id?: number
  toolName: string
  params: string
  result: string
  createTime: number
}

export class HistoryService {
  private db = DatabaseService.getInstance()

  /**
   * 保存历史记录
   */
  async save(record: Omit<HistoryRecord, 'id' | 'createTime'>): Promise<number> {
    const db = await this.db
    return await db.insert('history', {
      tool_name: record.toolName,
      params: record.params,
      result: record.result,
      create_time: Date.now()
    })
  }

  /**
   * 获取历史记录
   */
  async getList(limit: number = 20): Promise<HistoryRecord[]> {
    const db = await this.db
    const sql = `SELECT * FROM history ORDER BY create_time DESC LIMIT ?`
    const resultSet = await db.query(sql, [limit])

    const records: HistoryRecord[] = []
    while (resultSet.goToNextRow()) {
      records.push({
        id: resultSet.getLong(resultSet.getColumnIndex('id')),
        toolName: resultSet.getString(resultSet.getColumnIndex('tool_name')),
        params: resultSet.getString(resultSet.getColumnIndex('params')),
        result: resultSet.getString(resultSet.getColumnIndex('result')),
        createTime: resultSet.getLong(resultSet.getColumnIndex('create_time'))
      })
    }
    resultSet.close()
    return records
  }

  /**
   * 清空历史记录
   */
  async clear(): Promise<void> {
    const db = await this.db
    const predicates = new relationalStore.RdbPredicates('history')
    await db.delete(predicates)
  }
}

三、高级存储功能

3.1 数据存储流程图

不存在

存在

应用启动

检查数据库

创建数据库

打开数据库

创建表结构

初始化数据

应用正常运行

3.2 数据迁移

class DatabaseMigration {
  private static VERSION = 2
  
  static async migrate(db: relationalStore.RdbStore, oldVersion: number) {
    if (oldVersion < 1) {
      await this.createV1Tables(db)
    }
    if (oldVersion < 2) {
      await this.upgradeToV2(db)
    }
  }
  
  private static async createV1Tables(db: relationalStore.RdbStore) {
    const sql = `CREATE TABLE IF NOT EXISTS history (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      type TEXT,
      content TEXT,
      timestamp INTEGER
    )`
    await db.executeSql(sql)
  }
}

3.3 数据备份

class DataBackup {
  static async exportData(): Promise<string> {
    const preferences = await PreferencesService.getAll()
    const history = await HistoryService.getAll()
    
    const backup = {
      version: 1,
      timestamp: Date.now(),
      preferences,
      history
    }
    
    return JSON.stringify(backup)
  }
  
  static async importData(json: string) {
    const backup = JSON.parse(json)
    await PreferencesService.setAll(backup.preferences)
    await HistoryService.importAll(backup.history)
  }
}

四、性能优化

4.1 批量操作

async function batchInsert(items: HistoryItem[]) {
  const db = await DatabaseService.getDB()
  const values = items.map(item => [
    item.type, item.content, item.timestamp
  ])
  
  await db.executeSql(
    'INSERT INTO history (type, content, timestamp) VALUES (?, ?, ?)',
    values
  )
}

图 1 财务工具界面展示
在这里插入图片描述

五、小结

本文详细讲解了数据持久化:

  1. ✅ Preferences轻量级存储
  2. ✅ 关系型数据库
  3. ✅ 数据库封装
  4. ✅ 历史记录管理
  5. ✅ CRUD操作
  6. ✅ 数据迁移
  7. ✅ 数据备份
  8. ✅ 性能优化

系列文章导航
下期预告:鸿蒙多功能工具箱开发实战(十九)-应用设置页面开发

Logo

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

更多推荐