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 query = CloudDBZoneQuery.where(Book.class)
.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 getBooksByPage(int page, int pageSize) {
List books = new ArrayList<>();
CloudDBZoneQuery query = CloudDBZoneQuery.where(Book.class)
.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应用提供了稳定可靠的后端数据服务,使开发者能够专注于业务逻辑的实现,而无需担心数据存储和同步的复杂性。

建议在实际项目中:

封装统一的数据库访问层
实现完善的错误处理和日志记录
根据业务需求设计合理的数据模型
充分利用实时同步特性提升用户体验

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