news 2026/3/2 23:47:50

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/3/1 16:01:05

【Laravel开发者必看】:5步实现Laravel 13多模态权限控制

第一章&#xff1a;Laravel 13 多模态权限控制概述 Laravel 13 引入了全新的多模态权限控制系统&#xff0c;旨在应对现代 Web 应用中日益复杂的访问控制需求。该系统不仅支持传统的基于角色的权限管理&#xff08;RBAC&#xff09;&#xff0c;还融合了基于属性的访问控制&am…

作者头像 李华
网站建设 2026/3/1 17:56:45

NVIDIA多模态AI能力全景分析:高效生态系统、训练优化与落地实践

NVIDIA多模态AI能力全景分析&#xff1a;高效生态系统、训练优化与落地实践 一、技术架构体系 1.1 核心模型架构 NVILA/VILA视觉语言模型架构&#xff1a; ┌─────────────────────────────────────────┐ │ 输入层&#xff1a;图像…

作者头像 李华
网站建设 2026/2/28 19:02:53

【R语言时空可视化实战】:掌握环境监测数据动态展示的5大核心技巧

第一章&#xff1a;R语言时空可视化在环境监测中的应用概述R语言凭借其强大的统计分析与图形绘制能力&#xff0c;已成为环境监测领域中时空数据可视化的首选工具之一。通过整合地理信息系统&#xff08;GIS&#xff09;数据与时间序列观测值&#xff0c;研究人员能够直观揭示污…

作者头像 李华
网站建设 2026/3/1 6:10:27

【专家亲授】:重构PHP脱敏逻辑的7个关键节点(基于最新医疗标准)

第一章&#xff1a;医疗数据脱敏的合规性演进与PHP实现挑战随着《个人信息保护法》和《数据安全法》的相继实施&#xff0c;医疗数据的处理必须满足日益严格的合规要求。数据脱敏作为保护患者隐私的核心手段&#xff0c;其技术实现不仅需保障数据可用性&#xff0c;还需符合监管…

作者头像 李华
网站建设 2026/3/1 1:46:05

揭秘R Shiny文件上传黑科技:如何同时处理CSV、Excel、图像与JSON?

第一章&#xff1a;R Shiny 的多模态数据导入组件 在构建交互式数据应用时&#xff0c;R Shiny 提供了强大的多模态数据导入能力&#xff0c;支持从本地文件、数据库、API 接口等多种来源加载数据。通过合理设计输入控件与后端逻辑&#xff0c;用户可以灵活地上传和解析不同格式…

作者头像 李华