HarmonyOS 5数据同步:AGC云数据库的增删改查实战
前言
鸿蒙5(HarmonyOS 5)与AppGallery Connect(AGC)云数据库的结合为开发者提供了强大的数据存储和同步能力。本文将带您深入实战,掌握如何在鸿蒙5应用中实现AGC云数据库的增删改查(CRUD)操作,并实现多设备间的数据实时同步。
一、环境准备
1.1 开通AGC云数据库服务
登录AGC控制台
进入您的项目 > 选择应用 > 选择"云数据库"服务
点击"启用"按钮开通服务
1.2 配置DevEco Studio项目
在build.gradle中添加依赖:
dependencies {
// AGC云数据库核心库
implementation 'com.huawei.agconnect:agconnect-clouddb-harmony:1.8.0.300'
// AGC认证服务(用于用户鉴权)
implementation 'com.huawei.agconnect:agconnect-auth-harmony:1.8.0.300'
}
二、数据模型定义
2.1 创建对象类型
在AGC控制台创建Book对象类型,包含以下字段:
id (String, 主键)
title (String)
author (String)
price (Number)
publishDate (Date)
2.2 生成模型类
使用AGC插件自动生成模型类,或手动创建:
// Book.ts - 书籍数据模型
export default class Book {
// 必须包含的ZoneId字段
zoneId?: string;
constructor(
public id: string,
public title: string,
public author: string,
public price: number,
public publishDate: Date
) {}
// 转换为JSON对象
toJSON() {
return {
id: this.id,
title: this.title,
author: this.author,
price: this.price,
publishDate: this.publishDate.getTime()
};
}
// 从JSON解析
static fromJSON(json: any): Book {
return new Book(
json.id,
json.title,
json.author,
json.price,
new Date(json.publishDate)
);
}
}
三、初始化云数据库
3.1 创建数据库管理器
// CloudDBManager.java - 数据库管理类
import com.huawei.agconnect.cloud.database.AGConnectCloudDB;
import com.huawei.agconnect.cloud.database.CloudDBZone;
import com.huawei.agconnect.cloud.database.CloudDBZoneConfig;
import ohos.app.Context;
public class CloudDBManager {
private static final String ZONE_NAME = "BookZone";
private AGConnectCloudDB mCloudDB;
private CloudDBZone mCloudDBZone;
public void initCloudDB(Context context) {
// 1. 初始化AGC云数据库
mCloudDB = AGConnectCloudDB.getInstance(context);
mCloudDB.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo());
// 2. 配置数据库区域
CloudDBZoneConfig config = new CloudDBZoneConfig(
ZONE_NAME,
CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE,
CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC
);
config.setPersistenceEnabled(true);
// 3. 打开数据库区域
try {
mCloudDBZone = mCloudDB.openCloudDBZone(config, true);
} catch (Exception e) {
// 处理异常
}
}
public CloudDBZone getCloudDBZone() {
return mCloudDBZone;
}
}
四、CRUD操作实战
4.1 插入数据(Create)
// BookService.js - 数据操作服务
import agconnect from '@agconnect/api-harmony';
import '@agconnect/database-harmony';
export default class BookService {
// 添加书籍
static async addBook(book) {
try {
const cloudDB = agconnect.cloudDB();
const zone = cloudDB.cloudDBZone('BookZone');
// 插入数据
const result = await zone.executeUpsert('Book', [book]);
console.log('添加成功,影响行数:', result);
return result;
} catch (error) {
console.error('添加失败:', error);
throw error;
}
}
}
// 使用示例
const newBook = new Book(
'book_' + Date.now(),
'HarmonyOS开发指南',
'华为开发者',
59.9,
new Date()
);
BookService.addBook(newBook);
4.2 查询数据(Read)
4.2.1 查询所有书籍
// BookDao.java - 数据访问对象
import com.huawei.agconnect.cloud.database.CloudDBZoneQuery;
import com.huawei.agconnect.cloud.database.CloudDBZoneSnapshot;
import com.huawei.agconnect.cloud.database.exceptions.AGConnectCloudDBException;
import ohos.app.Context;
import java.util.ArrayList;
import java.util.List;
public class BookDao {
private CloudDBManager mDBManager;
public BookDao(Context context) {
mDBManager = new CloudDBManager();
mDBManager.initCloudDB(context);
}
public List<Book> getAllBooks() {
List<Book> books = new ArrayList<>();
CloudDBZoneQuery<Book> query = CloudDBZoneQuery.where(Book.class);
try {
CloudDBZoneSnapshot<Book> snapshot = mDBManager.getCloudDBZone()
.executeQuery(query, CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY);
while (snapshot.hasNext()) {
Book book = snapshot.next();
books.add(book);
}
snapshot.close();
} catch (AGConnectCloudDBException e) {
// 处理异常
}
return books;
}
}
4.2.2 条件查询
// BookService.ts - 条件查询
static async queryBooksByAuthor(author: string): Promise<Book[]> {
try {
const cloudDB = agconnect.cloudDB();
const zone = cloudDB.cloudDBZone('BookZone');
// 构建查询条件
const query = cloudDB.createQuery();
query.equalTo('author', author);
query.orderByAsc('price');
// 执行查询
const result = await zone.executeQuery(query);
const books: Book[] = [];
while (result.hasNext()) {
const book = result.next();
books.push(Book.fromJSON(book));
}
result.close();
return books;
} catch (error) {
console.error('查询失败:', error);
throw error;
}
}
4.3 更新数据(Update)
// BookService.js - 更新数据
static async updateBookPrice(bookId, newPrice) {
try {
const cloudDB = agconnect.cloudDB();
const zone = cloudDB.cloudDBZone('BookZone');
// 先查询要更新的书籍
const query = cloudDB.createQuery();
query.equalTo('id', bookId);
const result = await zone.executeQuery(query);
if (result.hasNext()) {
const book = result.next();
// 更新价格
book.price = newPrice;
// 执行更新
const updateResult = await zone.executeUpsert('Book', [book]);
console.log('更新成功,影响行数:', updateResult);
return updateResult;
}
result.close();
return 0;
} catch (error) {
console.error('更新失败:', error);
throw error;
}
}
4.4 删除数据(Delete)
// BookDao.java - 删除数据
public int deleteBook(String bookId) {
try {
// 构建查询条件
CloudDBZoneQuery
.equalTo("id", bookId);
// 执行删除
return mDBManager.getCloudDBZone().executeDelete(query);
} catch (AGConnectCloudDBException e) {
// 处理异常
return 0;
}
}
五、实时数据同步
5.1 注册数据监听
// BookService.ts - 实时数据监听
static registerBookListener(callback: (books: Book[]) => void): void {
const cloudDB = agconnect.cloudDB();
const zone = cloudDB.cloudDBZone('BookZone');
// 创建查询
const query = cloudDB.createQuery();
// 注册监听
const listener = zone.subscribeSnapshot(
query,
(snapshot) => {
const books: Book[] = [];
while (snapshot.hasNext()) {
const book = snapshot.next();
books.push(Book.fromJSON(book));
}
callback(books);
},
(error) => {
console.error('监听出错:', error);
}
);
// 返回取消监听的方法
return () => {
zone.unsubscribeSnapshot(listener);
};
}
// 使用示例
const unsubscribe = BookService.registerBookListener((books) => {
console.log('数据更新:', books);
});
// 当不需要监听时调用
// unsubscribe();
5.2 处理数据冲突
// ConflictHandler.java - 数据冲突处理
import com.huawei.agconnect.cloud.database.CloudDBZoneConflictPolicy;
import com.huawei.agconnect.cloud.database.CloudDBZoneObject;
import com.huawei.agconnect.cloud.database.CloudDBZoneSnapshot;
public class ConflictHandler implements CloudDBZoneConflictPolicy {
@Override
public CloudDBZoneObject resolveConflict(CloudDBZoneSnapshot cloudDBZoneSnapshot) {
// 获取服务器和本地数据
CloudDBZoneObject serverObj = cloudDBZoneSnapshot.getServerObject();
CloudDBZoneObject clientObj = cloudDBZoneSnapshot.getClientObject();
// 自定义冲突解决策略
if (serverObj instanceof Book && clientObj instanceof Book) {
Book serverBook = (Book) serverObj;
Book clientBook = (Book) clientObj;
// 示例:选择较新的版本
if (serverBook.getPublishDate().after(clientBook.getPublishDate())) {
return serverObj;
} else {
return clientObj;
}
}
// 默认返回服务器数据
return serverObj;
}
}
// 使用冲突处理器
CloudDBZoneConfig config = new CloudDBZoneConfig(...);
config.setConflictPolicy(new ConflictHandler());
六、最佳实践与优化
6.1 批量操作
// BookService.js - 批量操作
static async batchAddBooks(books: Book[]): Promise
try {
const cloudDB = agconnect.cloudDB();
const zone = cloudDB.cloudDBZone('BookZone');
// 批量插入
const result = await zone.executeUpsert('Book', books);
console.log('批量添加成功,影响行数:', result);
return result;
} catch (error) {
console.error('批量添加失败:', error);
throw error;
}
}
6.2 分页查询
// BookDao.java - 分页查询
public List
List
CloudDBZoneQuery
.orderByAsc("publishDate")
.limit(pageSize, (page - 1) * pageSize);
try {
CloudDBZoneSnapshot<Book> snapshot = mDBManager.getCloudDBZone()
.executeQuery(query, CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY);
while (snapshot.hasNext()) {
books.add(snapshot.next());
}
snapshot.close();
} catch (AGConnectCloudDBException e) {
// 处理异常
}
return books;
}
6.3 事务处理
// BookService.ts - 事务处理
static async transferBook(bookId: string, fromUserId: string, toUserId: string): Promise
try {
const cloudDB = agconnect.cloudDB();
const zone = cloudDB.cloudDBZone('BookZone');
// 开始事务
await zone.beginTransaction();
try {
// 1. 查询书籍
const query = cloudDB.createQuery();
query.equalTo('id', bookId);
const result = await zone.executeQuery(query);
if (!result.hasNext()) {
throw new Error('书籍不存在');
}
const book = result.next();
result.close();
// 2. 更新拥有者
book.ownerId = toUserId;
await zone.executeUpsert('Book', [book]);
// 3. 提交事务
await zone.commitTransaction();
return true;
} catch (error) {
// 回滚事务
await zone.rollbackTransaction();
throw error;
}
} catch (error) {
console.error('转移失败:', error);
throw error;
}
}
七、常见问题解决
数据同步延迟:
检查网络连接状态
确认CloudDBZone配置中同步策略设置正确
使用POLICY_QUERY_FROM_CLOUD_ONLY强制从云端获取最新数据
权限问题:
// config.json中添加权限
{
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
}
]
}
数据模型变更:
在AGC控制台修改对象类型后,需要重新生成模型类
对于已上线的应用,需谨慎处理数据迁移
性能优化:
对于频繁变化的数据,考虑使用本地缓存
合理设计数据模型,避免过度嵌套
结语
通过本文的实战演练,您已经掌握了在鸿蒙5应用中使用AGC云数据库实现完整CRUD操作的方法,以及实时数据同步的高级技巧。AGC云数据库为HarmonyOS应用提供了稳定可靠的后端数据服务,使开发者能够专注于业务逻辑的实现,而无需担心数据存储和同步的复杂性。
建议在实际项目中:
封装统一的数据库访问层
实现完善的错误处理和日志记录
根据业务需求设计合理的数据模型
充分利用实时同步特性提升用户体验

浙公网安备 33010602011771号