news 2026/4/16 13:46:59

Harmony学习之本地数据存储

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Harmony学习之本地数据存储

Harmony学习之本地数据存储

一、场景引入

小明在上一篇文章中学会了网络请求,现在他需要将用户登录信息、应用配置、商品收藏等数据持久化保存到本地,这样即使应用重启或网络断开,用户也能看到自己的个性化设置和历史数据。本篇文章将系统讲解HarmonyOS的本地数据存储机制,帮助小明实现数据的本地持久化。

二、本地数据存储方案对比

HarmonyOS提供了多种本地数据存储方式,每种方式都有其适用场景:

存储方式适用场景特点
Preferences用户配置、登录状态、开关设置轻量级键值对存储,类似SharedPreferences
关系型数据库结构化数据、复杂查询、事务支持基于SQLite,支持ACID事务
文件存储大文件、图片、文档支持二进制流和文本操作

三、Preferences轻量级存储

1. 核心概念

Preferences是HarmonyOS提供的轻量级键值对存储方案,适合存储用户配置、应用设置等小数据量信息。数据以Key-Value形式存储,支持字符串、数字、布尔值等基本数据类型。

2. 基本使用

// src/main/ets/common/StorageUtil.ts import preferences from '@ohos.data.preferences'; export class StorageUtil { private static instance: StorageUtil; private preferences: preferences.Preferences | null = null; // 获取Preferences实例 public static async getInstance(): Promise<StorageUtil> { if (!StorageUtil.instance) { StorageUtil.instance = new StorageUtil(); await StorageUtil.instance.init(); } return StorageUtil.instance; } // 初始化Preferences private async init() { try { this.preferences = await preferences.getPreferences( globalThis.getContext(), 'app_config' ); } catch (error) { console.error('初始化Preferences失败:', error); } } // 保存数据 public async save(key: string, value: any): Promise<boolean> { if (!this.preferences) return false; try { await this.preferences.put(key, value); await this.preferences.flush(); // 持久化到文件 return true; } catch (error) { console.error('保存数据失败:', error); return false; } } // 读取数据 public async get<T>(key: string, defaultValue: T): Promise<T> { if (!this.preferences) return defaultValue; try { return await this.preferences.get(key, defaultValue); } catch (error) { console.error('读取数据失败:', error); return defaultValue; } } // 删除数据 public async delete(key: string): Promise<boolean> { if (!this.preferences) return false; try { await this.preferences.delete(key); await this.preferences.flush(); return true; } catch (error) { console.error('删除数据失败:', error); return false; } } }

3. 实战应用:保存用户登录状态

// src/main/ets/pages/Login.ets import { StorageUtil } from '../common/StorageUtil'; @Entry @Component struct Login { @State username: string = ''; @State password: string = ''; build() { Column({ space: 20 }) { // ... 登录表单UI代码 Button('登录') .onClick(() => { this.handleLogin(); }) } } // 处理登录 private async handleLogin() { // 验证用户名密码... // 保存登录状态 const storage = await StorageUtil.getInstance(); await storage.save('isLoggedIn', true); await storage.save('username', this.username); // 跳转到首页 router.replaceUrl({ url: 'pages/Home' }); } }

四、关系型数据库存储

1. 核心概念

关系型数据库基于SQLite组件,提供结构化数据存储能力,支持复杂的查询、事务、索引等功能。适合存储用户信息、商品数据、订单记录等结构化数据。

2. 数据库创建与表定义

// src/main/ets/database/DatabaseHelper.ts import relationalStore from '@ohos.data.relationalStore'; // 用户表定义 export interface User { id?: number; name: string; email: string; age: number; createTime: number; } export class DatabaseHelper { private static instance: DatabaseHelper; private rdbStore: relationalStore.RdbStore | null = null; // 数据库配置 private readonly DB_NAME = 'app_database.db'; private readonly DB_VERSION = 1; // 创建用户表SQL private readonly CREATE_USER_TABLE = ` CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT UNIQUE NOT NULL, age INTEGER, createTime INTEGER DEFAULT (strftime('%s', 'now')) ) `; // 获取单例实例 public static async getInstance(): Promise<DatabaseHelper> { if (!DatabaseHelper.instance) { DatabaseHelper.instance = new DatabaseHelper(); await DatabaseHelper.instance.init(); } return DatabaseHelper.instance; } // 初始化数据库 private async init() { try { const context = globalThis.getContext(); const storeConfig: relationalStore.StoreConfig = { name: this.DB_NAME, securityLevel: relationalStore.SecurityLevel.S1 }; this.rdbStore = await relationalStore.getRdbStore(context, storeConfig); // 创建表 await this.rdbStore.executeSql(this.CREATE_USER_TABLE); console.log('数据库初始化成功'); } catch (error) { console.error('数据库初始化失败:', error); } } }

3. 增删改查操作

// 在DatabaseHelper类中继续添加方法 // 插入用户 public async insertUser(user: User): Promise<number> { if (!this.rdbStore) return -1; try { const valueBucket: relationalStore.ValuesBucket = { 'name': user.name, 'email': user.email, 'age': user.age }; const rowId = await this.rdbStore.insert('users', valueBucket); return rowId; } catch (error) { console.error('插入用户失败:', error); return -1; } } // 查询用户 public async queryUsers(): Promise<User[]> { if (!this.rdbStore) return []; try { const predicates = new relationalStore.RdbPredicates('users'); const columns = ['id', 'name', 'email', 'age', 'createTime']; const resultSet = await this.rdbStore.query(predicates, columns); const users: User[] = []; while (resultSet.goToNextRow()) { users.push({ id: resultSet.getLong(resultSet.getColumnIndex('id')), name: resultSet.getString(resultSet.getColumnIndex('name')), email: resultSet.getString(resultSet.getColumnIndex('email')), age: resultSet.getLong(resultSet.getColumnIndex('age')), createTime: resultSet.getLong(resultSet.getColumnIndex('createTime')) }); } resultSet.close(); return users; } catch (error) { console.error('查询用户失败:', error); return []; } } // 更新用户 public async updateUser(user: User): Promise<boolean> { if (!this.rdbStore || !user.id) return false; try { const predicates = new relationalStore.RdbPredicates('users'); predicates.equalTo('id', user.id); const valueBucket: relationalStore.ValuesBucket = { 'name': user.name, 'email': user.email, 'age': user.age }; const affectedRows = await this.rdbStore.update(valueBucket, predicates); return affectedRows > 0; } catch (error) { console.error('更新用户失败:', error); return false; } } // 删除用户 public async deleteUser(id: number): Promise<boolean> { if (!this.rdbStore) return false; try { const predicates = new relationalStore.RdbPredicates('users'); predicates.equalTo('id', id); const affectedRows = await this.rdbStore.delete(predicates); return affectedRows > 0; } catch (error) { console.error('删除用户失败:', error); return false; } }

4. 实战应用:用户管理

// src/main/ets/pages/UserList.ets import { DatabaseHelper, User } from '../database/DatabaseHelper'; @Entry @Component struct UserList { @State users: User[] = []; aboutToAppear() { this.loadUsers(); } build() { Column() { List() { ForEach(this.users, (user: User) => { ListItem() { Column() { Text(user.name) .fontSize(18) Text(user.email) .fontSize(14) .fontColor(Color.Gray) } .padding(10) } }) } .layoutWeight(1) } } // 加载用户列表 private async loadUsers() { const dbHelper = await DatabaseHelper.getInstance(); this.users = await dbHelper.queryUsers(); } }

五、文件存储

1. 核心概念

文件存储适用于保存图片、文档、大体积数据等二进制内容。HarmonyOS提供了文件系统API,支持文件的创建、读写、删除等操作。

2. 文件操作示例

// src/main/ets/common/FileUtil.ts import fs from '@ohos.file.fs'; export class FileUtil { // 写入文件 public static async writeFile(filePath: string, content: string): Promise<boolean> { try { const file = await fs.open(filePath, fs.OpenMode.CREATE | fs.OpenMode.WRITE); await fs.write(file.fd, content); await fs.close(file.fd); return true; } catch (error) { console.error('写入文件失败:', error); return false; } } // 读取文件 public static async readFile(filePath: string): Promise<string> { try { const file = await fs.open(filePath, fs.OpenMode.READ_ONLY); const stat = await fs.stat(filePath); const buffer = new ArrayBuffer(stat.size); await fs.read(file.fd, buffer); await fs.close(file.fd); const textDecoder = new util.TextDecoder(); return textDecoder.decode(buffer); } catch (error) { console.error('读取文件失败:', error); return ''; } } // 获取应用私有目录 public static getFilesDir(): string { const context = globalThis.getContext(); return context.filesDir; } }

六、最佳实践

1. 数据存储选型指南

Preferences适用场景

  • 用户配置信息(主题、语言、字体大小)
  • 登录状态、Token等敏感信息
  • 简单的开关设置

关系型数据库适用场景

  • 用户信息、商品列表等结构化数据
  • 需要复杂查询、排序、分页的场景
  • 需要事务支持的业务数据

文件存储适用场景

  • 图片、视频、文档等大文件
  • 日志文件、缓存数据
  • 需要导出/导入的数据

2. 性能优化建议

Preferences优化

  • 批量操作时先put再flush,减少IO次数
  • 避免存储大JSON对象,建议使用数据库
  • 及时清理不再使用的数据

数据库优化

  • 为常用查询字段创建索引
  • 使用事务处理批量操作
  • 避免在主线程执行耗时查询

文件存储优化

  • 大文件使用流式读写
  • 定期清理缓存文件
  • 使用临时目录存储临时文件

3. 错误处理与调试

// 完整的错误处理示例 try { const dbHelper = await DatabaseHelper.getInstance(); const users = await dbHelper.queryUsers(); // 处理数据... } catch (error) { console.error('数据库操作失败:', error); promptAction.showToast({ message: '数据加载失败,请稍后重试', duration: 2000 }); }

七、总结与行动建议

核心要点回顾

  1. Preferences:轻量级键值对存储,适合配置信息
  2. 关系型数据库:结构化数据存储,支持复杂查询
  3. 文件存储:大文件、二进制数据存储
  4. 选型原则:根据数据特点和业务需求选择合适的存储方案

行动建议

  1. 动手实践:创建用户配置页面,使用Preferences保存主题设置
  2. 数据库实战:实现一个简单的待办事项应用,使用数据库存储任务数据
  3. 文件操作:实现图片缓存功能,将网络图片保存到本地
  4. 性能优化:为数据库查询添加索引,优化查询性能

通过本篇文章的学习,你已经掌握了HarmonyOS本地数据存储的核心能力。下一篇文章将深入讲解列表渲染与性能优化,帮助你实现高效的数据展示和交互体验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/13 9:29:33

qubit初始化不难,难的是你不知道这5个隐藏陷阱

第一章&#xff1a;qubit初始化的基本概念与R包环境搭建在量子计算中&#xff0c;qubit&#xff08;量子比特&#xff09;是信息存储和处理的基本单位。与经典比特只能处于0或1状态不同&#xff0c;qubit可以处于叠加态&#xff0c;这使其具备强大的并行计算潜力。qubit初始化是…

作者头像 李华
网站建设 2026/4/1 16:22:12

生存分析核心代码曝光,R语言绘制临床数据曲线仅需5行命令

第一章&#xff1a;生存分析在临床研究中的核心价值生存分析作为统计学的重要分支&#xff0c;在临床研究中扮演着不可替代的角色。它专注于事件发生时间的建模与推断&#xff0c;尤其适用于研究患者从某一初始状态&#xff08;如确诊疾病&#xff09;到终点事件&#xff08;如…

作者头像 李华
网站建设 2026/4/16 10:55:30

英伟达在大模型训练基础设施领域的解决方案

英伟达在大模型训练基础设施领域提供了以韧性&#xff08;Resiliency&#xff09; 稳定性保障为核心的解决方案&#xff0c;覆盖工具、技术架构、测试体系等维度。 一、核心解决方案&#xff1a;Resiliency Extension 稳定性工具链 1. NVIDIA Resiliency Extension 定位&#…

作者头像 李华
网站建设 2026/4/16 12:31:30

美团没打赢的仗

出品I下海fallsea撰文I胡不知2025年12月15日&#xff0c;美团内部OA系统的一则通知&#xff0c;为历时五年的“团好货实验”画上句号&#xff1a;“暂停团好货业务运营&#xff0c;团队并入闪购事业部&#xff0c;聚焦即时零售。”几乎同时&#xff0c;美团APP底部“电商”入口…

作者头像 李华
网站建设 2026/4/15 10:56:29

纤维协程压力测试避坑指南(90%工程师都踩过的陷阱)

第一章&#xff1a;纤维协程压力测试的认知误区在高并发系统开发中&#xff0c;纤维协程&#xff08;Fiber/Coroutine&#xff09;因其轻量级特性被广泛采用。然而&#xff0c;在进行压力测试时&#xff0c;开发者常陷入若干认知误区&#xff0c;导致性能评估失真或系统上线后出…

作者头像 李华
网站建设 2026/4/16 7:39:31

【Java数组】--快速掌握二维数组

个人主页 文章目录前言一、二维数组1.1 什么是二维数组1.2 二维数组的声明1.3 使用二、多维数组三、三种初始化方式3.1 静态初始化3.1.1 语法3.1.2 怎么使用&#xff1f;3.2 动态初始化3.2.1 语法3.2.2 怎么使用&#xff1f;3.3 默认初始化四、数组的内存模型4.1 一维数组4.1.1…

作者头像 李华