HarmonyOS 鸿蒙Next中如何高效地进行批量数据操作?
HarmonyOS 鸿蒙Next中如何高效地进行批量数据操作? 1.在鸿蒙应用开发中,如何高效地进行批量数据操作? 2.批量插入、更新、删除数据时如何保证数据一致性?
3 回复
技术要点
- 数据库事务(Transaction)
- 批量插入优化
- 错误回滚机制
- 性能对比分析
- 原子性保证
完整实现代码
/**
* 批量操作示例 - DataService部分
*/
export class DataService {
private dbManager: DatabaseManager;
/**
* 批量添加人物(使用事务)
*/
public async batchAddPersons(persons: Person[]): Promise<string[]> {
const store = this.dbManager.getStore();
if (!store) throw new Error('数据库未初始化');
const ids: string[] = [];
const now = Date.now();
try {
// 1. 开启事务
await store.beginTransaction();
console.info(`开始批量添加${persons.length}个人物...`);
// 2. 批量插入数据
for (const person of persons) {
const id = this.generateId();
const insertSql = `
INSERT INTO lelv_persons
(id, name, relationship_type, relationship_tags, phone, avatar, contact_id, create_time, update_time)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`;
await store.executeSql(insertSql, [
id,
person.name,
person.relationshipType,
JSON.stringify(person.relationshipTags),
person.phone || null,
person.avatar || null,
person.contactId || null,
now,
now
]);
ids.push(id);
}
// 3. 提交事务
await store.commit();
console.info(`批量添加人物成功: ${ids.length}个`);
return ids;
} catch (error) {
// 4. 发生错误,回滚事务
await store.rollback(void 0);
console.error('批量添加人物失败:', JSON.stringify(error));
throw new Error('批量添加人物失败');
}
}
/**
* 批量添加记录(使用事务)
*/
public async batchAddRecords(records: HumanRecord[]): Promise<string[]> {
const store = this.dbManager.getStore();
if (!store) throw new Error('数据库未初始化');
const ids: string[] = [];
const now = Date.now();
try {
await store.beginTransaction();
console.info(`开始批量添加${records.length}条记录...`);
for (const record of records) {
const id = this.generateId();
const insertSql = `
INSERT INTO lelv_human_records
(id, type, event_type, custom_event_type, amount, event_time, person_id, location, remark, photos, custom_fields, create_time, update_time)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`;
await store.executeSql(insertSql, [
id,
record.type,
record.eventType,
record.customEventType || null,
record.amount,
record.eventTime,
record.personId,
record.location || null,
record.remark || null,
JSON.stringify(record.photos || []),
this.stringifyCustomFields(record.customFields),
now,
now
]);
ids.push(id);
}
await store.commit();
console.info(`批量添加记录成功: ${ids.length}条`);
return ids;
} catch (error) {
await store.rollback(void 0);
console.error('批量添加记录失败:', JSON.stringify(error));
throw new Error('批量添加记录失败');
}
}
/**
* 批量删除人物(使用事务,级联删除记录)
*/
public async batchDeletePersons(personIds: string[]): Promise<void> {
const store = this.dbManager.getStore();
if (!store) throw new Error('数据库未初始化');
try {
await store.beginTransaction();
console.info(`开始批量删除${personIds.length}个人物...`);
for (const personId of personIds) {
// 先删除相关的人情记录
await store.executeSql('DELETE FROM lelv_human_records WHERE person_id = ?', [personId]);
// 再删除人物
await store.executeSql('DELETE FROM lelv_persons WHERE id = ?', [personId]);
}
await store.commit();
console.info(`批量删除人物成功: ${personIds.length}个`);
} catch (error) {
await store.rollback(void 0);
console.error('批量删除人物失败:', JSON.stringify(error));
throw new Error('批量删除人物失败');
}
}
/**
* 批量删除记录(使用事务)
*/
public async batchDeleteRecords(recordIds: string[]): Promise<void> {
const store = this.dbManager.getStore();
if (!store) throw new Error('数据库未初始化');
try {
await store.beginTransaction();
console.info(`开始批量删除${recordIds.length}条记录...`);
for (const recordId of recordIds) {
await store.executeSql('DELETE FROM lelv_human_records WHERE id = ?', [recordId]);
}
await store.commit();
console.info(`批量删除记录成功: ${recordIds.length}条`);
} catch (error) {
await store.rollback(void 0);
console.error('批量删除记录失败:', JSON.stringify(error));
throw new Error('批量删除记录失败');
}
}
/**
* 批量更新记录(使用事务)
*/
public async batchUpdateRecords(records: HumanRecord[]): Promise<void> {
const store = this.dbManager.getStore();
if (!store) throw new Error('数据库未初始化');
try {
await store.beginTransaction();
console.info(`开始批量更新${records.length}条记录...`);
for (const record of records) {
const updateSql = `
UPDATE lelv_human_records
SET type = ?, event_type = ?, amount = ?, event_time = ?,
location = ?, remark = ?, update_time = ?
WHERE id = ?
`;
await store.executeSql(updateSql, [
record.type,
record.eventType,
record.amount,
record.eventTime,
record.location || null,
record.remark || null,
Date.now(),
record.id
]);
}
await store.commit();
console.info(`批量更新记录成功: ${records.length}条`);
} catch (error) {
await store.rollback(void 0);
console.error('批量更新记录失败:', JSON.stringify(error));
throw new Error('批量更新记录失败');
}
}
/**
* 清空所有数据(使用事务)
*/
public async clearAllData(): Promise<void> {
const store = this.dbManager.getStore();
if (!store) throw new Error('数据库未初始化');
try {
await store.beginTransaction();
console.info('开始清空所有数据...');
// 先删除记录
await store.executeSql('DELETE FROM lelv_human_records');
// 再删除人物
await store.executeSql('DELETE FROM lelv_persons');
// 重置设置
await store.executeSql('DELETE FROM lelv_app_settings WHERE key NOT IN (?, ?)',
['database_version', 'theme']);
await store.commit();
console.info('清空所有数据成功');
} catch (error) {
await store.rollback(void 0);
console.error('清空数据失败:', JSON.stringify(error));
throw new Error('清空数据失败');
}
}
/**
* 数据导入(使用事务,支持大批量)
*/
public async importData(data: {persons: Person[], records: HumanRecord[]}): Promise<void> {
const store = this.dbManager.getStore();
if (!store) throw new Error('数据库未初始化');
const now = Date.now();
try {
await store.beginTransaction();
console.info(`开始导入数据: ${data.persons.length}个人物, ${data.records.length}条记录`);
// 1. 导入人物
for (const person of data.persons) {
const insertSql = `
INSERT OR REPLACE INTO lelv_persons
(id, name, relationship_type, relationship_tags, phone, avatar, contact_id, create_time, update_time)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`;
await store.executeSql(insertSql, [
person.id,
person.name,
person.relationshipType,
JSON.stringify(person.relationshipTags),
person.phone || null,
person.avatar || null,
person.contactId || null,
person.createTime || now,
now
]);
}
// 2. 导入记录
for (const record of data.records) {
const insertSql = `
INSERT OR REPLACE INTO lelv_human_records
(id, type, event_type, custom_event_type, amount, event_time, person_id, location, remark, photos, custom_fields, create_time, update_time)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`;
await store.executeSql(insertSql, [
record.id,
record.type,
record.eventType,
record.customEventType || null,
record.amount,
record.eventTime,
record.personId,
record.location || null,
record.remark || null,
JSON.stringify(record.photos || []),
this.stringifyCustomFields(record.customFields),
record.createTime || now,
now
]);
}
await store.commit();
console.info('数据导入成功');
} catch (error) {
await store.rollback(void 0);
console.error('数据导入失败:', JSON.stringify(error));
throw new Error('数据导入失败');
}
}
}
事务处理原理
1. 事务的四大特性(ACID)
- 原子性(Atomicity): 事务中的所有操作要么全部成功,要么全部失败
- 一致性(Consistency): 事务前后数据保持一致状态
- 隔离性(Isolation): 多个事务并发执行互不干扰
- 持久性(Durability): 事务提交后永久保存
2. 事务执行流程
try {
await store.beginTransaction(); // 1. 开启事务
// 2. 执行多个SQL操作
await store.executeSql(sql1, params1);
await store.executeSql(sql2, params2);
await store.commit(); // 3. 提交事务
} catch (error) {
await store.rollback(void 0); // 4. 回滚事务
throw error;
}
3. 回滚机制
当任何一条SQL执行失败时:
await store.rollback(void 0); // 撤销所有操作
性能对比
逐条插入 vs 批量事务插入
// 方式1: 逐条插入(慢)
for (const person of persons) {
await this.addPerson(person); // 每次都提交
}
// 耗时: 1000条 ≈ 10秒
// 方式2: 批量事务插入(快)
await store.beginTransaction();
for (const person of persons) {
await store.executeSql(sql, params);
}
await store.commit(); // 一次性提交
// 耗时: 1000条 ≈ 0.5秒
性能提升: 约20倍
使用示例
1. 批量导入数据
const persons: Person[] = [
{id: '1', name: '张三', relationshipType: 'friend', ...},
{id: '2', name: '李四', relationshipType: 'relative', ...},
// ... 更多数据
];
const dataService = DataService.getInstance();
const ids = await dataService.batchAddPersons(persons);
console.info(`成功添加${ids.length}个人物`);
2. 批量删除数据
const personIds = ['1', '2', '3', '4', '5'];
await dataService.batchDeletePersons(personIds);
3. 数据完整导入
const backupData = {
persons: [...],
records: [...]
};
await dataService.importData(backupData);
最佳实践
1. 合理控制批量大小
// 分批处理,避免单次事务过大
const batchSize = 100;
for (let i = 0; i < persons.length; i += batchSize) {
const batch = persons.slice(i, i + batchSize);
await this.batchAddPersons(batch);
}
2. 错误处理要完整
try {
await store.beginTransaction();
// ... 操作
await store.commit();
} catch (error) {
await store.rollback(void 0); // 必须回滚
throw new Error(`操作失败: ${error.message}`);
}
3. 记录操作日志
console.info(`开始批量操作: ${records.length}条`);
await store.beginTransaction();
// ... 操作
await store.commit();
console.info(`批量操作成功`);
4. 使用INSERT OR REPLACE
// 避免主键冲突,支持更新
INSERT OR REPLACE INTO table_name VALUES (...)
避坑指南
1. ❌ 忘记回滚事务
// 错误示例
try {
await store.beginTransaction();
// ... 操作
await store.commit();
} catch (error) {
// 忘记回滚!
throw error;
}
// 正确示例
try {
await store.beginTransaction();
// ... 操作
await store.commit();
} catch (error) {
await store.rollback(void 0); // 必须回滚
throw error;
}
2. ❌ 事务嵌套
// 不支持事务嵌套
await store.beginTransaction();
await store.beginTransaction(); // ❌ 错误
3. ❌ 事务中执行长时间操作
// 事务应尽快提交
await store.beginTransaction();
// ❌ 不要在事务中执行复杂计算或网络请求
await someComplexCalculation();
await store.commit();
4. ❌ 不检查返回值
// 应该检查操作结果
const result = await store.executeSql(sql, params);
if (result === undefined) {
throw new Error('SQL执行失败');
}
性能优化建议
- 使用预编译语句: 相同SQL多次执行时复用
- 合理设置批量大小: 100-1000条为宜
- 避免频繁commit: 批量操作使用一个事务
- 建立合适索引: 加速查询和删除
- 定期VACUUM: 回收空间,优化性能
实际应用场景
- 数据导入: Excel导入大量记录
- 数据迁移: 版本升级时迁移数据
- 批量删除: 清理历史数据
- 数据同步: 云端同步大量数据
- 备份恢复: 恢复备份文件
总结
本文实现了完整的批量操作方案:
- ✅ 事务保证数据一致性
- ✅ 批量插入性能提升20倍
- ✅ 完善的错误回滚机制
- ✅ 支持大批量数据导入
- ✅ 级联删除保证数据完整性
更多关于HarmonyOS 鸿蒙Next中如何高效地进行批量数据操作?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
HarmonyOS Next中批量数据操作可通过分布式数据管理框架实现。使用KVStore或关系型数据库的批量接口,如executeBatch()方法进行事务处理。结合DataShareExtensionAbility跨应用同步数据。利用ResultSet高效遍历查询结果,通过Predicates批量筛选。
在HarmonyOS Next中进行高效批量数据操作,推荐使用关系型数据库(RDB)的批处理能力。以下是关键方法:
-
使用RDB批处理接口
- 通过
RdbStore.executeSqlBatch()方法执行批量SQL操作,将多个操作封装在单次事务中,显著减少I/O开销。 - 示例:
const sqlBatch = [ "INSERT INTO user (name, age) VALUES (?, ?)", "UPDATE user SET age = ? WHERE name = ?", "DELETE FROM user WHERE age < ?" ]; const argsBatch = [ ["张三", 25], [26, "张三"], [18] ]; await rdbStore.executeSqlBatch(sqlBatch, argsBatch);
- 通过
-
保证数据一致性
- 批处理默认在事务中执行,所有操作要么全部成功,要么全部回滚,确保原子性。
- 可结合
beginTransaction()、commit()、rollback()手动控制事务边界,应对复杂逻辑。
-
性能优化建议
- 批量操作前预编译SQL语句,避免重复解析。
- 合理设置批处理大小(如每次100-500条),平衡内存与性能。
- 对于超大数据集,考虑分批次处理并适时提交事务,避免内存压力。
-
使用对象关系映射(ORM)
- 通过
@ohos.data.relationalStore的ORM能力,批量操作对象实体,简化代码并保持性能。
- 通过
这种方式直接利用数据库引擎的优化,是鸿蒙Next中处理批量数据的标准实践。

