鸿蒙5离线数据处理:AGC云数据库的同步策略详解

一、AGC云数据库与离线同步概述

  1. AGC云数据库核心特性
    AGC(AppGallery Connect)云数据库提供:

​​实时同步​​:设备间数据自动同步
​​离线优先​​:无网络时本地操作,恢复连接后自动同步
​​多端一致​​:跨设备数据一致性保障
​​安全规则​​:细粒度的数据访问控制
2. 离线同步工作原理
graph LR
A[本地操作] --> B[本地数据库]
B --> C{网络可用?}
C -->|是| D[同步到云端]
C -->|否| E[队列缓存]
D --> F[其他设备同步]

二、环境配置与初始化

  1. 添加依赖
    在entry/build.gradle中配置:

dependencies {
// AGC核心
implementation 'com.huawei.agconnect:agconnect-core-harmony:1.6.5.300'
// 云数据库
implementation 'com.huawei.agconnect:agconnect-clouddb-harmony:1.6.5.300'
// 认证服务(可选)
implementation 'com.huawei.agconnect:agconnect-auth-harmony:1.6.5.300'
}
2. 初始化云数据库
创建CloudDBManager.ets:

import clouddb from '@hw-agconnect/clouddb';
import agconnect from '@hw-agconnect/core';

export class CloudDBManager {
private static instance: CloudDBManager | null = null;
private cloudDB: clouddb.CloudDBZone | null = null;

private constructor() {}

public static getInstance(): CloudDBManager {
if (!CloudDBManager.instance) {
CloudDBManager.instance = new CloudDBManager();
}
return CloudDBManager.instance;
}

// 初始化云数据库
async initialize(): Promise {
try {
// 1. 初始化AGC
agconnect.instance().init();

// 2. 创建CloudDB实例
const cloudDBZoneConfig = new clouddb.CloudDBZoneConfig(
'QuickStartDemo', // 数据库名称
clouddb.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE, // 同步策略
clouddb.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC // 访问权限
);

// 3. 打开数据库
this.cloudDB = await clouddb.CloudDBZone.open(cloudDBZoneConfig);

console.log('CloudDB初始化成功');
} catch (error) {
console.error('CloudDB初始化失败:', error);
throw error;
}
}

// 获取数据库实例
getCloudDB(): clouddb.CloudDBZone {
if (!this.cloudDB) {
throw new Error('CloudDB未初始化');
}
return this.cloudDB;
}
}
三、数据模型定义与同步策略

  1. 定义对象类型
    创建model/BookInfo.ets:

@Class
export class BookInfo {
@Field()
id: string = '';

@Field({ isIndex: true })
bookName: string = '';

@Field()
author: string = '';

@Field()
price: number = 0;

@Field({ isLocal: true }) // 标记为本地字段,不同步
lastReadTime: number = 0;

@Field({ isNeedEncrypt: true }) // 加密字段
secretNote: string = '';

@Field()
@PrimaryKey()
get primaryKey(): string {
return this.id;
}
}
2. 注册对象类型
在CloudDBManager中添加:

private objectTypes = [BookInfo];

async initialize(): Promise {
// ...原有代码...

// 注册对象类型
await clouddb.CloudDBZone.registerObjectClass(
this.objectTypes.map(type => type.name)
);

console.log('对象类型注册成功');
}
四、离线数据操作实现

  1. 新增数据(离线优先)
    // 在CloudDBManager中添加
    async addBook(book: BookInfo): Promise {
    try {
    const db = this.getCloudDB();
    book.id = this.generateId(); // 生成唯一ID

    // 设置最后阅读时间(本地字段)
    book.lastReadTime = new Date().getTime();

    // 执行插入
    await db.executeUpsert([book]);
    console.log('书籍添加成功:', book.id);
    } catch (error) {
    console.error('添加书籍失败:', error);
    throw error;
    }
    }

private generateId(): string {
return 'book_' + Math.random().toString(36).substr(2, 9);
}
2. 查询数据(本地缓存优先)
// 在CloudDBManager中添加
async queryBooks(
conditions?: clouddb.CloudDBZoneQuery,
policy: clouddb.CloudDBZoneQueryPolicy = clouddb.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY
): Promise<BookInfo[]> {
try {
const db = this.getCloudDB();

// 默认查询所有书籍
const query = conditions || clouddb.CloudDBZoneQuery.where(BookInfo);

// 执行查询
const snapshot = await db.executeQuery(
query,
policy // 查询策略
);

// 获取结果
const books: BookInfo[] = [];
while (snapshot.hasNext()) {
books.push(snapshot.next());
}
snapshot.release();

return books;
} catch (error) {
console.error('查询书籍失败:', error);
throw error;
}
}
3. 更新与删除操作
// 在CloudDBManager中添加
async updateBook(book: BookInfo): Promise {
try {
const db = this.getCloudDB();
book.lastReadTime = new Date().getTime();
await db.executeUpsert([book]);
console.log('书籍更新成功:', book.id);
} catch (error) {
console.error('更新书籍失败:', error);
throw error;
}
}

async deleteBook(bookId: string): Promise {
try {
const db = this.getCloudDB();
const book = new BookInfo();
book.id = bookId;
await db.executeDelete([book]);
console.log('书籍删除成功:', bookId);
} catch (error) {
console.error('删除书籍失败:', error);
throw error;
}
}
五、同步策略与冲突解决

  1. 同步策略配置
    策略类型 说明 适用场景
    CLOUDDBZONE_LOCAL_ONLY 仅本地操作 临时数据
    CLOUDDBZONE_CLOUD_CACHE 本地优先,自动同步 大多数场景
    CLOUDDBZONE_CLOUD_ONLY 仅云端操作 强一致性要求

  2. 冲突解决策略
    // 在CloudDBManager中添加
    async syncWithConflictResolution(): Promise {
    try {
    const db = this.getCloudDB();

    // 1. 获取未同步操作
    const pendingWrites = await db.getPendingWrites();

    // 2. 处理冲突
    for (const write of pendingWrites) {
    try {
    // 尝试同步
    await db.executeUpsert([write.object]);

    // 同步成功后删除本地记录
    await db.removePendingWrite(write);
    } catch (syncError) {
    console.warn(同步冲突: ${write.object.id}, syncError);

    // 冲突处理方案1:使用服务器版本
    const serverVersion = await this.queryBookFromServer(write.object.id);
    await db.executeUpsert([serverVersion]);

    // 冲突处理方案2:合并字段(自定义逻辑)
    // this.mergeConflict(write.object, serverVersion);

    // 标记为已处理
    await db.removePendingWrite(write);
    }
    }
    } catch (error) {
    console.error('同步处理失败:', error);
    }
    }

private async queryBookFromServer(bookId: string): Promise {
const db = this.getCloudDB();
const query = clouddb.CloudDBZoneQuery.where(BookInfo)
.equalTo('id', bookId);

const snapshot = await db.executeQuery(
query,
clouddb.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY
);

if (snapshot.hasNext()) {
return snapshot.next();
}
throw new Error('未找到书籍');
}
六、网络状态监听与自动同步

  1. 网络状态监听
    创建NetworkManager.ets:

import connection from '@ohos.net.connection';

export class NetworkManager {
private static instance: NetworkManager | null = null;
private netHandle: connection.NetHandle;

private constructor() {
this.netHandle = connection.getDefaultNet();
}

public static getInstance(): NetworkManager {
if (!NetworkManager.instance) {
NetworkManager.instance = new NetworkManager();
}
return NetworkManager.instance;
}

// 检查网络状态
isConnected(): boolean {
try {
return this.netHandle.hasInternet();
} catch (error) {
console.error('检查网络状态失败:', error);
return false;
}
}

// 监听网络变化
onNetworkChange(callback: (connected: boolean) => void): void {
connection.on('netAvailable', (data: { netHandle: connection.NetHandle }) => {
callback(data.netHandle.hasInternet());
});

connection.on('netUnavailable', () => {
callback(false);
});
}
}
2. 自动同步策略实现
在CloudDBManager中添加:

private syncInterval: number = 0;
private isSyncing: boolean = false;

// 启动自动同步
startAutoSync(interval: number = 30000): void {
this.syncInterval = interval;
this.setupNetworkListener();
this.runSyncLoop();
}

private setupNetworkListener(): void {
NetworkManager.getInstance().onNetworkChange(async (connected) => {
if (connected) {
console.log('网络恢复,触发同步');
await this.syncData();
}
});
}

private async runSyncLoop(): Promise {
while (this.syncInterval > 0) {
await new Promise(resolve => setTimeout(resolve, this.syncInterval));

if (NetworkManager.getInstance().isConnected() && !this.isSyncing) {
await this.syncData();
}
}
}

private async syncData(): Promise {
if (this.isSyncing) return;

this.isSyncing = true;
try {
console.log('开始数据同步...');

// 1. 同步本地更改到云端
await this.syncWithConflictResolution();

// 2. 从云端获取最新数据
await this.pullLatestData();

console.log('数据同步完成');
} catch (error) {
console.error('同步过程中出错:', error);
} finally {
this.isSyncing = false;
}
}

private async pullLatestData(): Promise {
try {
// 示例:同步所有书籍数据
const db = this.getCloudDB();
const query = clouddb.CloudDBZoneQuery.where(BookInfo);

// 使用POLICY_QUERY_FROM_CLOUD_ONLY强制从云端获取
await db.executeQuery(
query,
clouddb.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY
);
} catch (error) {
console.error('拉取最新数据失败:', error);
throw error;
}
}
七、实战案例:离线优先的阅读应用

  1. 页面实现:图书列表
    @Entry
    @Component
    struct BookListPage {
    @State books: BookInfo[] = [];
    @State loading: boolean = true;
    @State networkStatus: string = '检查中...';

    private cloudDB = CloudDBManager.getInstance();

    onPageShow() {
    this.loadBooks();
    this.checkNetwork();
    }

    async loadBooks() {
    this.loading = true;
    try {
    // 优先从本地缓存查询
    this.books = await this.cloudDB.queryBooks(
    undefined,
    clouddb.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_LOCAL_ONLY
    );

    // 网络可用时同步最新数据
    if (NetworkManager.getInstance().isConnected()) {
    const cloudBooks = await this.cloudDB.queryBooks();
    this.books = cloudBooks;
    }
    } catch (error) {
    console.error('加载书籍失败:', error);
    } finally {
    this.loading = false;
    }
    }

    async checkNetwork() {
    const isConnected = NetworkManager.getInstance().isConnected();
    this.networkStatus = isConnected ? '已连接' : '离线模式';
    }

    build() {
    Column() {
    Text('我的书库')
    .fontSize(24)
    .margin(10);

    Text(状态: ${this.networkStatus})
    .fontColor(this.networkStatus === '离线模式' ? Color.Red : Color.Green);

    if (this.loading) {
    LoadingProgress()
    .margin(20);
    } else {
    List({ space: 10 }) {
    ForEach(this.books, (book: BookInfo) => {
    ListItem() {
    BookItem({ book: book })
    }
    })
    }
    .width('100%')
    .height('80%')
    }
    }
    .width('100%')
    .height('100%')
    }
    }

@Component
struct BookItem {
@Prop book: BookInfo;

build() {
Row() {
Column() {
Text(this.book.bookName)
.fontSize(18);
Text(this.book.author)
.fontSize(14)
.fontColor(Color.Gray);
}
.margin(10)

Text(¥${this.book.price.toFixed(2)})
.fontSize(16)
.fontColor(Color.Blue)
.margin({ right: 15 })
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
}
2. 页面实现:添加/编辑图书
@Entry
@Component
struct BookEditPage {
@State book: BookInfo = new BookInfo();
@State isNew: boolean = true;
@State saving: boolean = false;

private cloudDB = CloudDBManager.getInstance();

onPageShow() {
const params = router.getParams();
if (params && params.book) {
this.book = params.book;
this.isNew = false;
}
}

async saveBook() {
this.saving = true;
try {
if (this.isNew) {
await this.cloudDB.addBook(this.book);
} else {
await this.cloudDB.updateBook(this.book);
}

// 返回并刷新列表
router.back();
} catch (error) {
console.error('保存失败:', error);
} finally {
this.saving = false;
}
}

build() {
Column({ space: 15 }) {
Text(this.isNew ? '添加新书' : '编辑书籍')
.fontSize(22)
.margin(10);

TextInput({ text: this.book.bookName })
.placeholder('书名')
.onChange((value: string) => {
this.book.bookName = value;
})
.width('90%');

TextInput({ text: this.book.author })
.placeholder('作者')
.onChange((value: string) => {
this.book.author = value;
})
.width('90%');

TextInput({ text: this.book.price.toString() })
.placeholder('价格')
.type(InputType.Number)
.onChange((value: string) => {
this.book.price = parseFloat(value) || 0;
})
.width('90%');

Button(this.saving ? '保存中...' : '保存')
.width(200)
.height(50)
.backgroundColor(Color.Blue)
.enabled(!this.saving)
.onClick(() => {
this.saveBook();
})
}
.width('100%')
.height('100%')
.padding(20)
}
}
八、性能优化与调试技巧

  1. 批量操作优化
    // 在CloudDBManager中添加
    async batchAddBooks(books: BookInfo[]): Promise {
    try {
    const db = this.getCloudDB();

    // 分配ID
    books.forEach(book => {
    book.id = this.generateId();
    book.lastReadTime = new Date().getTime();
    });

    // 分批处理(每批50条)
    const batchSize = 50;
    for (let i = 0; i < books.length; i += batchSize) {
    const batch = books.slice(i, i + batchSize);
    await db.executeUpsert(batch);
    console.log(已批量添加 ${batch.length} 本书籍);
    }
    } catch (error) {
    console.error('批量添加失败:', error);
    throw error;
    }
    }

  2. 数据同步状态监控
    // 在CloudDBManager中添加
    async getSyncStatus(): Promise<{
    pendingWrites: number,
    lastSyncTime: number,
    syncError?: string
    }> {
    try {
    const db = this.getCloudDB();
    const pendingWrites = await db.getPendingWrites();

    return {
    pendingWrites: pendingWrites.length,
    lastSyncTime: Date.now() // 实际应用中应记录真实时间
    };
    } catch (error) {
    return {
    pendingWrites: 0,
    lastSyncTime: 0,
    syncError: error.message
    };
    }
    }

  3. 调试日志配置
    // 在应用启动时设置
    clouddb.setLogLevel(clouddb.CloudDBLogLevel.DEBUG);

// 监听数据库事件
clouddb.on('event', (event) => {
console.log('CloudDB事件:', event.type, event.data);

if (event.type === 'syncComplete') {
console.log('数据同步完成');
} else if (event.type === 'syncError') {
console.error('同步错误:', event.data);
}
});
总结
通过本文的学习,你已经掌握了在HarmonyOS 5应用中实现AGC云数据库离线同步的核心技术:

​​环境配置​​:正确初始化云数据库服务
​​数据建模​​:定义支持离线同步的数据结构
​​CRUD操作​​:实现离线优先的数据访问
​​同步策略​​:配置冲突解决和网络状态感知
​​实战案例​​:构建完整的离线优先应用
AGC云数据库的离线同步能力为HarmonyOS应用提供了:

​​无缝用户体验​​:网络中断不影响核心功能
​​数据一致性​​:自动解决多设备同步冲突
​​开发效率​​:简化本地和云端数据管理
在实际项目中,你还可以进一步探索:

更复杂的冲突解决策略
数据变更订阅通知
与AGC认证服务的深度集成
大数据量下的性能调优

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