引言

数据存储是每个应用必不可少的基础功能。本文将介绍鸿蒙系统中常用的数据存储方式,从简单的首选项到结构化数据存储,帮助开发者快速掌握数据持久化技术。

1. 首选项存储

1.1 基础用法

首选项(Preferences)适合存储简单的键值对数据:

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

@Entry
@Component
struct PreferencesDemo {
    @State username: string = '';
    @State isLoggedIn: boolean = false;
    
    async aboutToAppear() {
        // 获取首选项实例
        let storage = await preferences.getPreferences(getContext(), 'myStore');
        
        // 读取数据
        this.username = await storage.get('username', '未登录');
        this.isLoggedIn = await storage.get('isLoggedIn', false);
    }
    
    build() {
        Column() {
            // 显示用户信息
            Text(`当前用户:${this.username}`)
                .fontSize(16)
                .margin(10)
            
            // 登录按钮
            Button('登录')
                .onClick(async () => {
                    let storage = await preferences.getPreferences(getContext(), 'myStore');
                    // 保存登录状态
                    await storage.put('username', '张三');
                    await storage.put('isLoggedIn', true);
                    // 提交更改
                    await storage.flush();
                    
                    // 更新界面
                    this.username = '张三';
                    this.isLoggedIn = true;
                })
                .margin(10)
            
            // 退出按钮
            Button('退出登录')
                .onClick(async () => {
                    let storage = await preferences.getPreferences(getContext(), 'myStore');
                    // 清除登录状态
                    await storage.delete('username');
                    await storage.put('isLoggedIn', false);
                    await storage.flush();
                    
                    // 更新界面
                    this.username = '未登录';
                    this.isLoggedIn = false;
                })
                .margin(10)
        }
        .width('100%')
        .height('100%')
    }
}

1.2 数据类型支持

首选项支持多种数据类型:

async function saveUserSettings() {
    let storage = await preferences.getPreferences(getContext(), 'settings');
    
    // 保存不同类型的数据
    await storage.put('age', 25);                     // 数字
    await storage.put('name', '张三');                // 字符串
    await storage.put('isVip', true);                 // 布尔值
    await storage.put('scores', [80, 90, 85]);        // 数组
    await storage.put('lastLogin', new Date().getTime()); // 时间戳
    
    // 一次性提交所有更改
    await storage.flush();
}

async function loadUserSettings() {
    let storage = await preferences.getPreferences(getContext(), 'settings');
    
    // 读取数据,并提供默认值
    let age = await storage.get('age', 0);
    let name = await storage.get('name', '');
    let isVip = await storage.get('isVip', false);
    let scores = await storage.get('scores', []);
    let lastLogin = await storage.get('lastLogin', 0);
    
    console.info(`用户信息:${name}, ${age}岁, VIP:${isVip}`);
    console.info(`成绩:${scores.join(',')}`);
    console.info(`上次登录:${new Date(lastLogin).toLocaleString()}`);
}

2. 轻量级数据库

2.1 创建数据表

使用关系型数据库存储结构化数据:

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

// 定义数据库配置
const STORE_CONFIG = {
    name: 'TodoList.db',
    securityLevel: relationalStore.SecurityLevel.S1
};

// 定义表结构
const SQL_CREATE_TABLE = `
    CREATE TABLE IF NOT EXISTS todos (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        content TEXT,
        completed INTEGER DEFAULT 0,
        createTime INTEGER
    )
`;

@Entry
@Component
struct DatabaseDemo {
    private rdbStore: relationalStore.RdbStore = null;
    
    async aboutToAppear() {
        // 获取数据库实例
        this.rdbStore = await relationalStore.getRdbStore(getContext(), STORE_CONFIG);
        // 创建表
        await this.rdbStore.executeSql(SQL_CREATE_TABLE);
    }
    
    build() {
        Column() {
            Text('数据库示例')
                .fontSize(20)
                .margin(10)
        }
    }
}

2.2 基本操作

实现待办事项的增删改查:

// 添加待办事项
async function addTodo(title: string, content: string) {
    // 准备数据
    const todo = {
        title: title,
        content: content,
        completed: 0,
        createTime: new Date().getTime()
    };
    
    // 执行插入
    await this.rdbStore.insert('todos', todo);
}

// 查询待办列表
async function queryTodos() {
    // 构建查询语句
    let predicates = new relationalStore.RdbPredicates('todos');
    predicates.orderByDesc('createTime');
    
    // 执行查询
    let resultSet = await this.rdbStore.query(predicates);
    
    let todos = [];
    while (resultSet.goToNextRow()) {
        todos.push({
            id: resultSet.getLong('id'),
            title: resultSet.getString('title'),
            content: resultSet.getString('content'),
            completed: resultSet.getLong('completed'),
            createTime: resultSet.getLong('createTime')
        });
    }
    
    // 关闭结果集
    resultSet.close();
    return todos;
}

// 更新待办状态
async function updateTodoStatus(id: number, completed: boolean) {
    // 准备更新数据
    const values = {
        completed: completed ? 1 : 0
    };
    
    // 构建更新条件
    let predicates = new relationalStore.RdbPredicates('todos');
    predicates.equalTo('id', id);
    
    // 执行更新
    await this.rdbStore.update(values, predicates);
}

// 删除待办事项
async function deleteTodo(id: number) {
    // 构建删除条件
    let predicates = new relationalStore.RdbPredicates('todos');
    predicates.equalTo('id', id);
    
    // 执行删除
    await this.rdbStore.delete(predicates);
}

3. 实战示例:待办事项应用

3.1 完整实现

结合UI和数据存储实现一个简单的待办事项应用:

@Entry
@Component
struct TodoListPage {
    @State todos: Array<Todo> = [];
    private rdbStore: relationalStore.RdbStore = null;
    
    async aboutToAppear() {
        // 初始化数据库
        this.rdbStore = await relationalStore.getRdbStore(getContext(), STORE_CONFIG);
        await this.rdbStore.executeSql(SQL_CREATE_TABLE);
        // 加载数据
        this.loadTodos();
    }
    
    async loadTodos() {
        this.todos = await this.queryTodos();
    }
    
    build() {
        Column() {
            // 标题
            Text('我的待办')
                .fontSize(24)
                .fontWeight(FontWeight.Bold)
                .margin({ top: 20, bottom: 20 })
            
            // 添加按钮
            Button('添加待办')
                .onClick(() => {
                    this.showAddDialog();
                })
                .margin(10)
            
            // 待办列表
            List() {
                ForEach(this.todos, (item: Todo) => {
                    ListItem() {
                        Row() {
                            // 完成状态
                            Toggle({ type: ToggleType.Checkbox, isOn: item.completed === 1 })
                                .onChange((isOn) => {
                                    this.updateTodoStatus(item.id, isOn);
                                })
                            
                            // 待办内容
                            Column() {
                                Text(item.title)
                                    .fontSize(16)
                                    .fontWeight(FontWeight.Medium)
                                
                                if (item.content) {
                                    Text(item.content)
                                        .fontSize(14)
                                        .opacity(0.6)
                                }
                            }
                            .margin({ left: 10 })
                            
                            // 删除按钮
                            Button({ type: ButtonType.Circle, stateEffect: true }) {
                                Image($r('app.media.ic_delete'))
                                    .width(20)
                                    .height(20)
                            }
                            .onClick(() => {
                                this.deleteTodo(item.id);
                            })
                        }
                        .width('100%')
                        .padding(10)
                    }
                })
            }
            .width('100%')
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#F5F5F5')
    }
    
    // 显示添加对话框
    private showAddDialog() {
        AlertDialog.show({
            title: '添加待办',
            message: '请输入待办事项',
            primaryButton: {
                value: '确定',
                action: async () => {
                    // 添加待办
                    await this.addTodo('新待办', '');
                    // 刷新列表
                    this.loadTodos();
                }
            },
            secondaryButton: {
                value: '取消',
                action: () => {
                    console.info('取消添加');
                }
            }
        });
    }
}

总结

本文介绍了鸿蒙系统中两种常用的数据存储方式:首选项存储和轻量级数据库。通过实际的代码示例,展示了如何在应用中实现数据的持久化存储。开发者可以根据实际需求,选择合适的存储方式,实现数据管理功能。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐