AGC云数据库入门:为鸿蒙5应用打造实时数据存储

一、AGC云数据库概述
AppGallery Connect(AGC)云数据库是华为为鸿蒙应用开发者提供的端云协同数据库服务,基于HarmonyOS 5.0的分布式能力,可以实现数据的实时同步和跨设备访问。主要特点包括:

​​实时同步​​:数据变更实时推送到所有设备
​​离线优先​​:支持离线操作,网络恢复后自动同步
​​多端一致​​:保证跨设备数据一致性
​​安全可靠​​:提供完善的数据加密和访问控制
二、环境准备与配置

  1. 在AGC控制台启用云数据库
    登录AGC控制台
    选择你的项目和应用
    在"构建" → "云数据库"中启用服务
    创建云数据库实例并设置默认存储区域
  2. 项目配置
    在entry/build.gradle中添加依赖:

dependencies {
implementation 'com.huawei.agconnect:agconnect-clouddb-harmony:1.6.5.300'
implementation 'com.huawei.agconnect:agconnect-auth-harmony:1.6.5.300'
}
三、数据模型定义

  1. 创建对象类型
    在AGC控制台的云数据库页面中,创建你的第一个对象类型。例如我们创建一个User对象类型:

字段名 类型 是否主键 是否索引
id String 是 是
name String 否 是
age Integer 否 否
email String 否 是
2. 本地模型类定义
在项目中创建对应的模型类User.ets:

export class User {
id: string = '';
name: string = '';
age: number = 0;
email: string = '';

// 必须提供无参构造函数
constructor() {}

// 带参构造函数
constructorWithFields(id: string, name: string, age: number, email: string) {
this.id = id;
this.name = name;
this.age = age;
this.email = email;
}

// 必须实现序列化方法
serialize(): Object {
return {
id: this.id,
name: this.name,
age: this.age,
email: this.email
};
}

// 必须实现反序列化方法
deserialize(obj: Object): void {
if (obj && typeof obj === 'object') {
this.id = obj['id'] || '';
this.name = obj['name'] || '';
this.age = obj['age'] || 0;
this.email = obj['email'] || '';
}
}
}
四、初始化云数据库
创建CloudDBManager.ets管理类:

import clouddb from '@hw-agconnect/clouddb-harmony';
import { User } from './User';

const TAG = 'CloudDBManager';

export class CloudDBManager {
private static instance: CloudDBManager = null;
private cloudDBZone = null;

// 单例模式
public static getInstance(): CloudDBManager {
if (!CloudDBManager.instance) {
CloudDBManager.instance = new CloudDBManager();
}
return CloudDBManager.instance;
}

// 初始化云数据库
async initCloudDB(context): Promise {
try {
// 1. 创建Cloud DB实例
const cloudDB = clouddb.CloudDBZoneWrapper.getInstance();

// 2. 创建对象类型
await cloudDB.createObjectType(User);

// 3. 打开云数据库区域
const config = {
zoneName: "QuickStartDemo",
syncEnabled: true,
accessMode: clouddb.CloudDBZoneAccessMode.CLOUDDBZONE_PUBLIC
};
this.cloudDBZone = await cloudDB.openCloudDBZone(config);

console.info(TAG, 'CloudDB initialized successfully');
return true;
} catch (err) {
console.error(TAG, 'Failed to initialize CloudDB:', err);
return false;
}
}

// 获取数据库区域
getCloudDBZone() {
return this.cloudDBZone;
}

// 关闭云数据库区域
async closeCloudDBZone() {
if (this.cloudDBZone) {
await clouddb.CloudDBZoneWrapper.getInstance().closeCloudDBZone(this.cloudDBZone);
this.cloudDBZone = null;
}
}
}
五、基本CRUD操作实现

  1. 插入数据
    // 在CloudDBManager类中添加
    async addUser(user: User): Promise {
    if (!this.cloudDBZone) {
    console.error(TAG, 'CloudDBZone is not initialized');
    return false;
    }

    try {
    const result = await this.cloudDBZone.executeUpsert(user);
    console.info(TAG, User added successfully: ${JSON.stringify(result)});
    return true;
    } catch (err) {
    console.error(TAG, 'Failed to add user:', err);
    return false;
    }
    }

  2. 查询数据
    // 在CloudDBManager类中添加
    async queryAllUsers(): Promise<User[]> {
    if (!this.cloudDBZone) {
    console.error(TAG, 'CloudDBZone is not initialized');
    return [];
    }

    try {
    const query = clouddb.CloudDBZoneQuery.where(User).equalTo('id', '*');
    const users = await this.cloudDBZone.executeQuery(query, User);
    console.info(TAG, Query users successfully, count: ${users.length});
    return users;
    } catch (err) {
    console.error(TAG, 'Failed to query users:', err);
    return [];
    }
    }

// 条件查询示例
async queryUsersByName(name: string): Promise<User[]> {
if (!this.cloudDBZone) {
console.error(TAG, 'CloudDBZone is not initialized');
return [];
}

try {
const query = clouddb.CloudDBZoneQuery.where(User).equalTo('name', name);
const users = await this.cloudDBZone.executeQuery(query, User);
console.info(TAG, Query users by name successfully, count: ${users.length});
return users;
} catch (err) {
console.error(TAG, 'Failed to query users by name:', err);
return [];
}
}
3. 更新数据
// 在CloudDBManager类中添加
async updateUser(user: User): Promise {
if (!this.cloudDBZone) {
console.error(TAG, 'CloudDBZone is not initialized');
return false;
}

try {
const result = await this.cloudDBZone.executeUpsert(user);
console.info(TAG, User updated successfully: ${JSON.stringify(result)});
return true;
} catch (err) {
console.error(TAG, 'Failed to update user:', err);
return false;
}
}
4. 删除数据
// 在CloudDBManager类中添加
async deleteUser(user: User): Promise {
if (!this.cloudDBZone) {
console.error(TAG, 'CloudDBZone is not initialized');
return false;
}

try {
const result = await this.cloudDBZone.executeDelete(user);
console.info(TAG, User deleted successfully: ${JSON.stringify(result)});
return true;
} catch (err) {
console.error(TAG, 'Failed to delete user:', err);
return false;
}
}
六、实时数据监听
AGC云数据库的强大功能之一是实时数据变更通知:

// 在CloudDBManager类中添加
private subscription = null;

// 订阅数据变更
async subscribeUserChanges(callback: (changedUsers: User[]) => void): Promise {
if (!this.cloudDBZone) {
console.error(TAG, 'CloudDBZone is not initialized');
return false;
}

try {
const query = clouddb.CloudDBZoneQuery.where(User);

this.subscription = await this.cloudDBZone.subscribeSnapshot(
query,
clouddb.CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_DEFAULT,
(snapshot, error) => {
if (error) {
console.error(TAG, 'Snapshot error:', error);
return;
}

const users: User[] = [];
if (snapshot) {
const snapshotObjects = snapshot.getSnapshotObjects();
for (let i = 0; i < snapshotObjects.length; i++) {
const user = new User();
user.deserialize(snapshotObjects[i]);
users.push(user);
}
}

callback(users);
}
);

console.info(TAG, 'Subscribe user changes successfully');
return true;
} catch (err) {
console.error(TAG, 'Failed to subscribe user changes:', err);
return false;
}
}

// 取消订阅
async unsubscribeUserChanges() {
if (this.subscription) {
await this.cloudDBZone.unsubscribeSnapshot(this.subscription);
this.subscription = null;
console.info(TAG, 'Unsubscribe user changes successfully');
}
}
七、完整示例:用户管理界面
// UserManagementPage.ets
import { CloudDBManager } from '../clouddb/CloudDBManager';
import { User } from '../model/User';

@Entry
@Component
struct UserManagementPage {
private cloudDBManager: CloudDBManager = CloudDBManager.getInstance();
@State users: User[] = [];
@State loading: boolean = true;
@State newUserName: string = '';
@State newUserAge: string = '';
@State newUserEmail: string = '';

aboutToAppear() {
this.initCloudDB();
}

async initCloudDB() {
// 初始化云数据库
const success = await this.cloudDBManager.initCloudDB(getContext(this));
if (success) {
// 查询所有用户
this.loadUsers();

// 订阅数据变更
await this.cloudDBManager.subscribeUserChanges((changedUsers) => {
this.users = changedUsers;
});
}
this.loading = false;
}

async loadUsers() {
this.users = await this.cloudDBManager.queryAllUsers();
}

async addUser() {
if (!this.newUserName || !this.newUserEmail) {
promptAction.showToast({ message: '请输入姓名和邮箱' });
return;
}

const user = new User();
user.id = this.generateId();
user.name = this.newUserName;
user.age = parseInt(this.newUserAge) || 0;
user.email = this.newUserEmail;

const success = await this.cloudDBManager.addUser(user);
if (success) {
promptAction.showToast({ message: '用户添加成功' });
this.newUserName = '';
this.newUserAge = '';
this.newUserEmail = '';
} else {
promptAction.showToast({ message: '用户添加失败' });
}
}

generateId(): string {
return 'user_' + new Date().getTime();
}

build() {
Column() {
// 添加用户表单
Column() {
TextInput({ placeholder: '姓名' })
.width('90%')
.height(40)
.margin(5)
.onChange((value: string) => {
this.newUserName = value;
})

TextInput({ placeholder: '年龄', type: InputType.Number })
.width('90%')
.height(40)
.margin(5)
.onChange((value: string) => {
this.newUserAge = value;
})

TextInput({ placeholder: '邮箱' })
.width('90%')
.height(40)
.margin(5)
.onChange((value: string) => {
this.newUserEmail = value;
})

Button('添加用户')
.width('90%')
.height(40)
.margin(10)
.onClick(() => this.addUser())
}
.width('100%')
.padding(10)
.borderRadius(10)
.backgroundColor('#f0f0f0')

// 用户列表
List({ space: 10 }) {
if (this.loading) {
ListItem() {
LoadingProgress()
.width(30)
.height(30)
}
.height(100)
} else {
ForEach(this.users, (user: User) => {
ListItem() {
Row() {
Column() {
Text(user.name)
.fontSize(18)
.fontWeight(FontWeight.Bold)
Text(年龄: ${user.age})
.fontSize(14)
Text(邮箱: ${user.email})
.fontSize(14)
.fontColor('#666')
}
.layoutWeight(1)

Button('删除')
.width(60)
.height(30)
.fontSize(12)
.onClick(async () => {
const success = await this.cloudDBManager.deleteUser(user);
if (success) {
promptAction.showToast({ message: '删除成功' });
} else {
promptAction.showToast({ message: '删除失败' });
}
})
}
.width('100%')
.padding(10)
}
.borderRadius(10)
.backgroundColor(Color.White)
.shadow({ radius: 3, color: '#999', offsetX: 1, offsetY: 1 })
})
}
}
.width('100%')
.layoutWeight(1)
.margin({ top: 10 })
}
.width('100%')
.height('100%')
.padding(10)
}
}
八、高级功能与最佳实践

  1. 数据加密
    // 在初始化配置中添加加密选项
    const config = {
    zoneName: "SecureDemo",
    syncEnabled: true,
    accessMode: clouddb.CloudDBZoneAccessMode.CLOUDDBZONE_PUBLIC,
    encryptionKey: "your-256-bit-encryption-key" // 32字节的加密密钥
    };

  2. 数据同步策略
    // 查询时指定同步策略
    const query = clouddb.CloudDBZoneQuery.where(User)
    .equalTo('name', 'John')
    .setQueryPolicy(clouddb.CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY);

  3. 批量操作
    async batchAddUsers(users: User[]): Promise {
    if (!this.cloudDBZone) {
    console.error(TAG, 'CloudDBZone is not initialized');
    return false;
    }

    try {
    const result = await this.cloudDBZone.executeUpsertAll(users);
    console.info(TAG, Batch add users successfully: ${JSON.stringify(result)});
    return true;
    } catch (err) {
    console.error(TAG, 'Failed to batch add users:', err);
    return false;
    }
    }

  4. 事务处理
    async transferPoints(fromUserId: string, toUserId: string, points: number): Promise {
    if (!this.cloudDBZone) {
    console.error(TAG, 'CloudDBZone is not initialized');
    return false;
    }

    try {
    await this.cloudDBZone.executeTransaction(async (transaction) => {
    // 查询源用户
    const fromUserQuery = clouddb.CloudDBZoneQuery.where(User).equalTo('id', fromUserId);
    const fromUsers = await transaction.executeQuery(fromUserQuery, User);
    if (fromUsers.length === 0) {
    throw new Error('Source user not found');
    }
    const fromUser = fromUsers[0];

    // 查询目标用户
    const toUserQuery = clouddb.CloudDBZoneQuery.where(User).equalTo('id', toUserId);
    const toUsers = await transaction.executeQuery(toUserQuery, User);
    if (toUsers.length === 0) {
    throw new Error('Target user not found');
    }
    const toUser = toUsers[0];

    // 检查余额
    if (fromUser.points < points) {
    throw new Error('Insufficient points');
    }

    // 更新余额
    fromUser.points -= points;
    toUser.points += points;

    // 保存更改
    await transaction.executeUpsert(fromUser);
    await transaction.executeUpsert(toUser);
    });

    console.info(TAG, 'Points transferred successfully');
    return true;
    } catch (err) {
    console.error(TAG, 'Failed to transfer points:', err);
    return false;
    }
    }
    九、常见问题与解决方案
    ​​数据同步延迟​​:
    检查网络连接
    确认syncEnabled设置为true
    适当调整同步策略
    ​​查询性能问题​​:
    为常用查询字段创建索引
    限制查询结果数量
    使用条件查询缩小范围
    ​​认证失败​​:
    确保已正确集成AGC认证服务
    检查用户登录状态
    验证数据库访问权限设置
    ​​存储空间不足​​:
    清理不必要的数据
    考虑使用分页查询
    联系华为技术支持提升配额
    十、总结
    通过本文,你已经掌握了如何在鸿蒙5应用中集成AGC云数据库:

配置云数据库环境
定义数据模型
实现基本的CRUD操作
使用实时数据监听
应用高级功能如事务处理
AGC云数据库为鸿蒙应用提供了强大的数据存储和同步能力,结合HarmonyOS 5.0的分布式特性,可以轻松实现跨设备数据一致性。建议从简单示例开始,逐步尝试更复杂的功能,为你的应用打造出色的数据体验。

posted @ 2025-06-28 22:23  暗雨YA  阅读(138)  评论(0)    收藏  举报