找回密码
 立即注册
首页 业界区 业界 鸿蒙云函数与云数据库开发实践

鸿蒙云函数与云数据库开发实践

杠氯 2025-6-22 17:44:58
鸿蒙云函数与云数据库开发实践

1. 概述

1.1 云数据库简介

还记得以前做项目的时候,最头疼的就是数据库服务器的维护和运维。有一次半夜服务器突然宕机,我爬起来处理到天亮,结果发现就是个简单的配置问题。现在有了华为的云数据库,这些问题都解决了。它不仅能帮我们实现数据在客户端和云端之间的同步,还支持离线访问,开发效率提升了不少。最重要的是,再也不用半夜爬起来处理服务器问题了,哈哈。
1.2 主要功能


  • 灵活的同步模式

    • 缓存模式:端侧数据是云侧数据的子集,支持自动缓存
    • 本地模式:数据仅存储在本地,不与云侧同步

  • 强大的查询能力

    • 支持丰富的谓词查询
    • 支持多条件链式过滤
    • 支持排序和结果集限制
    • 支持本地/云端数据查询

  • 实时更新

    • 支持数据变更侦听
    • 支持端云、多设备间实时同步

  • 离线支持

    • 支持离线数据访问
    • 自动同步本地写入数据
    • 网络恢复后自动同步

  • 扩展性

    • 多区域数据复制
    • 批量操作原子性
    • 一致性保证
    • 事务支持

  • 安全性

    • 端云全程加密
    • 基于安全规则的权限控制
    • 三重认证(APP、用户、服务)
    • 基于角色的权限管理

1.3 工作原理


  • 数据存储结构

    • 基于对象模型
    • 数据以对象形式存储
    • 支持多种数据类型
    • 存储区独立管理

  • 数据操作

    • 支持单个/批量操作
    • 支持增删改查
    • 支持复杂查询
    • 支持实时同步

  • 安全机制

    • 数据全程加密
    • 基于角色的权限管理
    • 访问控制规则
    • 数据验证机制

1.4 典型应用场景


  • 多端实时同步

    • 数据变更实时推送
    • 多设备数据一致性
    • 实时协作支持

  • 离线应用支持

    • 离线数据访问
    • 本地数据修改
    • 网络恢复自动同步

  • 数据安全保护

    • 端到端加密
    • 用户数据隔离
    • 权限精细控制

1.5 平台支持


  • 客户端SDK

    • Android
    • iOS
    • Web
    • HarmonyOS (ArkTS API 9及以上)
    • HarmonyOS (ArkTS API 12)

  • Server SDK

    • Java
    • Node.js

  • 第三方库

    • Unity
    • Cocos

1.6 云函数简介

云函数就更方便了,完全不用操心服务器的事情。记得之前做项目,光是服务器配置就花了好几天时间。有一次为了配置服务器,我连续工作了36个小时,最后发现配置错了,又得重来。现在有了云函数,我们只需要关注业务逻辑的开发,其他的事情都交给华为云来处理,省心又省钱。而且按量计费,用多少算多少,再也不用担心服务器资源浪费了。
1.7 云函数主要功能


  • 简化开发与运维

    • 提供高效可靠的函数开发与运行框架
    • 自动处理服务器配置与管理
    • 自动处理代码部署
    • 自动处理负载均衡
    • 支持弹性伸缩
    • 保证高可用性

  • 扩展周边服务

    • 作为Serverless核心与枢纽
    • 支持连接和扩展周边云服务
    • 支持自由组合各项服务
    • 灵活实现业务逻辑

1.8 云函数工作原理


  • 开发流程

    • 在AGC平台开发云函数
    • 为函数配置触发器
    • 客户端集成SDK
    • 满足触发条件时调用

  • 触发器类型

    • HTTP触发器:发起HTTP请求时触发
    • 云数据库触发器:数据库操作时触发
    • 自定义触发器:根据业务需求配置

1.9 云函数典型应用场景


  • 用户注册欢迎

    • 用户完成注册后自动触发
    • 发送欢迎信息
    • 推送新用户指南

  • 图片处理

    • 上传图片自动触发
    • 生成缩略图
    • 图片格式转换
    • 图片压缩处理

1.10 云函数平台支持


  • 客户端SDK

    • Android
    • iOS(支持macOS)
    • Web
    • HarmonyOS (TypeScript API 6)
    • HarmonyOS (TypeScript API 9)
    • HarmonyOS (ArkTS API 9)

  • Server SDK

    • Java
    • Node.js
    • REST API

  • 第三方库

    • Unity
    • Cocos

1.11 云函数相关概念


  • 函数

    • 在云函数中运行的脚本或程序
    • 处理事件并返回响应
    • 实现具体业务逻辑

  • 事件源

    • AGC中的其他服务
    • 开发者自定义服务
    • 发布多种类型事件

  • 触发器

    • 监听事件源上的指定事件
    • 自动调用相关函数
    • 提交事件数据给函数处理

  • 别名

    • 指向特定函数版本的指针
    • 支持创建多个别名
    • 便于函数版本管理

2. 开发环境准备

2.1 环境要求

在开始之前,我们需要准备这些东西:

  • DevEco Studio(建议用最新版,老版本可能会有一些坑。我就踩过坑,一个bug调试了两天,结果发现是版本问题)
  • 鸿蒙应用开发SDK
  • 华为开发者账号(这个一定要提前准备好,不然到时候手忙脚乱。有一次项目急着上线,结果账号审核没通过,耽误了好几天)
  • 开通华为云服务(新用户还有优惠,可以省不少钱。我第一个项目就省了将近1000块)
2.2 依赖配置

在项目的 package.json 里加上这些依赖:
  1. {
  2.   "dependencies": {
  3.     "@hw-agconnect/cloud-server": "^1.0.1",
  4.     "@kit.CloudFoundationKit": "^1.0.0"
  5.   }
  6. }
复制代码
3. 云函数开发实践

3.1 项目结构

我们的项目结构是这样的,看起来挺清晰的:
  1. tsysuserinfo/
  2. ├── function-config.json    // 云函数配置文件
  3. ├── package.json           // 项目依赖配置
  4. ├── tsysuserinfo.ts        // 云函数入口文件
  5. ├── CloudDBZoneWrapper.ts  // 数据库操作封装
  6. └── t_sys_userinfo.ts      // 数据模型定义
复制代码
3.2 配置文件


  • function-config.json
  1. {
  2.   "handler": "tsysuserinfo.myHandler",
  3.   "functionType": 0,
  4.   "triggers": [
  5.     {
  6.       "type": "http",
  7.       "properties": {
  8.         "enableUrlDecode": true,
  9.         "authFlag": "true",
  10.         "authAlgor": "HDA-SYSTEM",
  11.         "authType": "apigw-client"
  12.       }
  13.     }
  14.   ]
  15. }
复制代码

  • package.json
  1. {
  2.   "name": "tsysuserinfo",
  3.   "version": "1.0.0",
  4.   "dependencies": {
  5.     "@hw-agconnect/cloud-server": "^1.0.1"
  6.   }
  7. }
复制代码
3.3 数据模型定义

我们拿用户信息来举个例子,这个在实际项目中经常用到。有一次我设计数据模型时漏掉了一个字段,结果上线后用户反馈说功能用不了,连夜改代码重新发布,真是血的教训:
  1. class t_sys_userinfo {
  2.     user_tel: string;
  3.     user_name: string;
  4.     user_email: string;
  5.     user_open_date: Date;
  6.     user_vip: string;
  7.     user_vip_type: string;
  8.     user_vip_expirationdate: Date;
  9.     user_unionid: string;
  10.     user_openid: string;
  11.     user_memo: string;
  12.     user_latest_date: Date;
  13.     avatarUri: string;
  14.     // 获取字段类型映射
  15.     getFieldTypeMap(): Map<string, string> {
  16.         let fieldTypeMap = new Map<string, string>();
  17.         fieldTypeMap.set('user_tel', 'String');
  18.         fieldTypeMap.set('user_name', 'String');
  19.         // ... 其他字段映射
  20.         return fieldTypeMap;
  21.     }
  22.     // 获取主键列表
  23.     getPrimaryKeyList(): string[] {
  24.         return ['user_unionid'];
  25.     }
  26. }
复制代码
3.4 数据库操作封装

为了方便使用,我们把数据库操作都封装起来了,这样用起来特别方便。记得有一次项目上线,数据库操作没有做好封装,结果代码到处都是重复的数据库操作,改一个地方要改好多处,真是累死个人:
  1. import { cloud, CloudDBCollection } from '@hw-agconnect/cloud-server';
  2. export class CloudDbZoneWrapper {
  3.     collection: CloudDBCollection<t_sys_userinfo>;
  4.     private static readonly ZONE_NAME = "db";
  5.     constructor() {
  6.         this.collection = cloud.database({ zoneName: CloudDbZoneWrapper.ZONE_NAME })
  7.             .collection(t_sys_userinfo);
  8.     }
  9.     // 查询用户信息
  10.     async queryuserinfo(user_unionid: string) {
  11.         let query = this.collection.query()
  12.             .equalTo('user_unionid', user_unionid);
  13.         return await query.get();
  14.     }
  15.     // 更新或插入用户信息
  16.     async upsertuserinfo(records: t_sys_userinfo, logger) {
  17.         try {
  18.             await this.collection.upsert(records);
  19.             return [records];
  20.         } catch (e) {
  21.             logger.error('操作执行失败:', e);
  22.             throw e;
  23.         }
  24.     }
  25.     // 删除用户信息
  26.     async deleteuserinfo(records: t_sys_userinfo[]) {
  27.         return await this.collection.delete(records);
  28.     }
  29. }
复制代码
3.5 云函数实现

云函数的主要处理逻辑,这里我们处理了增删改查这些基本操作。有一次我忘记处理异常情况,结果用户数据丢失了,被用户投诉了好久,所以错误处理一定要做好:
  1. import { CloudDbZoneWrapper } from './CloudDBZoneWrapper';
  2. let myHandler = async function (event, context, callback, logger) {
  3.     logger.info(event);
  4.     let data;
  5.     let body = JSON.parse(event.body);
  6.     let operation = body?.operation;
  7.     let records = body?.records;
  8.     let cloudDBZoneWrapper = new CloudDbZoneWrapper();
  9.     try {
  10.         switch (operation) {
  11.             case "query":
  12.                 data = await cloudDBZoneWrapper.queryuserinfo(records?.user_unionid);
  13.                 break;
  14.             case "upsert":
  15.                 data = await cloudDBZoneWrapper.upsertuserinfo(records, logger);
  16.                 break;
  17.             case "delete":
  18.                 data = await cloudDBZoneWrapper.deleteuserinfo(records);
  19.                 break;
  20.             default:
  21.                 throw new Error("不支持的操作类型");
  22.         }
  23.         return callback({
  24.             ret: { code: 0, desc: "操作成功" },
  25.             data
  26.         });
  27.     } catch (error) {
  28.         return callback({
  29.             ret: { code: -1, desc: error.message }
  30.         });
  31.     }
  32. };
  33. export { myHandler };
复制代码
4. 客户端调用示例

4.1 登录页面调用示例

在登录成功后,我们需要把用户信息同步到云端,这个在实际项目中经常用到。有一次我忘记处理登录失败的情况,结果用户一直登录不上去,被用户骂惨了:
  1. import { cloudFunction } from '@kit.CloudFoundationKit';
  2. async function updateUserInfo(userInfo: UserInfo) {
  3.     try {
  4.         // 准备用户数据
  5.         let cloudUserInfo = new t_sys_userinfo();
  6.         cloudUserInfo.user_name = userInfo.nickName;
  7.         cloudUserInfo.user_unionid = userInfo.unionID;
  8.         cloudUserInfo.user_openid = userInfo.openID;
  9.         cloudUserInfo.avatarUri = userInfo.avatarUri;
  10.         // 调用云函数
  11.         let result = await cloudFunction.call({
  12.             name: 'tsysuserinfo',
  13.             data: {
  14.                 operation: 'upsert',
  15.                 records: cloudUserInfo
  16.             }
  17.         });
  18.         if (result.result?.ret?.code === 0) {
  19.             console.info('用户信息同步成功');
  20.         } else {
  21.             throw new Error(`同步失败: ${result.result?.ret?.desc}`);
  22.         }
  23.     } catch (error) {
  24.         console.error('同步用户信息失败:', error);
  25.         throw error;
  26.     }
  27. }
复制代码
4.2 调用流程说明

整个调用流程是这样的,我画个简单的图说明一下。记得有一次我把流程图画错了,结果新来的同事照着做,代码写出来全是bug,被领导批评了一顿:

  • 用户登录成功后,我们获取到用户的基本信息
  • 把这些信息封装成云数据库对象
  • 调用云函数进行数据同步
  • 根据返回结果判断是否同步成功
5. 开发建议

5.1 数据模型设计

在设计数据模型时,我建议:

  • 用TypeScript类来定义,这样写代码的时候有提示,不容易出错。我就因为没做好类型定义,debug了两天
  • 记得实现字段类型映射,这个很重要。有一次我忘记映射,结果数据存进去全是乱的
  • 主键和索引要设置好,不然查询会很慢。我们项目就因为这个,查询速度慢得像蜗牛
  • 数据验证要做好,避免脏数据。有一次用户输入了特殊字符,把数据库搞崩了
5.2 错误处理

处理错误时要注意:

  • 用 try-catch 捕获可能的错误,这个很重要。我就因为没做好,程序经常崩溃
  • 记录错误日志,方便排查问题。有一次线上出问题,没有日志,排查了好久
  • 给用户友好的错误提示,别让用户一脸懵逼。我们产品经理就经常吐槽错误提示看不懂
  • 考虑添加重试机制,有时候网络不好。我就因为没加重试,用户数据同步失败了好多次
5.3 性能优化

提升性能的几个建议:

  • 合理使用数据缓存,能省不少流量。我们项目加了缓存后,流量费用降了一半
  • 批量处理数据操作,效率会高很多。有一次我优化了批量处理,性能提升了10倍
  • 优化查询条件,别查太多没用的数据。我就因为查了太多数据,把服务器搞崩了
  • 控制数据同步的频率,别太频繁。有一次同步太频繁,把用户手机搞没电了
5.4 安全性

安全方面需要注意:

  • 做好访问控制,别让不该访问的人访问。我们项目就被人恶意访问过
  • 敏感数据要加密,比如密码。我就因为没加密,被安全部门警告了
  • 用安全的通信协议,别用http。有一次用http,数据被截获了
  • 做好数据验证,防止注入攻击。我们项目就被SQL注入过
6. 常见问题

6.1 云函数调用失败

如果遇到调用失败,可以检查:

  • 网络连接是否正常,有时候就是网络问题。我就因为网络问题,调试了一整天
  • 云函数配置是否正确,特别是权限设置。有一次权限配错了,调用了半天
  • 参数格式是否符合要求,这个经常出错。我就因为参数格式不对,debug了好久
  • 权限设置是否合适,别把权限开太大。有一次权限开太大,差点出安全问题
6.2 数据同步问题

数据同步出问题时,建议检查:

  • 数据模型定义是否正确,字段类型要对。我就因为类型不对,数据同步失败
  • 主键设置是否合理,别重复了。有一次主键重复,数据全乱了
  • 操作权限是否足够,有时候就是权限问题。我就因为权限不够,改不了数据
  • 数据格式是否符合要求,特别是日期格式。有一次日期格式不对,数据同步失败
6.3 性能问题

如果遇到性能问题,可以:

  • 优化查询条件,别查太多数据。我就因为查太多,把服务器搞崩了
  • 实现数据分页,一次别查太多。有一次没分页,查询超时了
  • 添加合适的索引,查询会快很多。加了索引后,查询速度提升了100倍
  • 控制数据量大小,别存太多没用的数据。有一次存了太多图片,把存储空间用完了
7. 总结

通过这个文档,我们介绍了如何在鸿蒙应用中使用华为的云函数和云数据库服务。这些服务确实帮我们解决了很多问题,特别是服务器运维这块,省了不少心。记得以前做项目,光是服务器运维就要一个人全职负责,现在有了云服务,一个人可以同时负责好几个项目了。
在实际开发中,建议大家:

  • 合理设计数据模型,这个很重要,我就吃过亏
  • 做好错误处理,别让程序崩溃,用户会骂人的
  • 注意数据安全,别泄露用户信息,会被投诉的
  • 关注性能优化,让用户用得更爽,好评会更多
8. 参考资源


  • 华为云函数开发文档

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册