经验1

在鸿蒙(HarmonyOS)的关系型数据库开发中,SQL查询语法遵循SQLite标准,以下是关键语法说明及注意事项:

1. 基础SELECT语法

SELECT 列名 FROM 表名 [WHERE 条件]
  • 示例:SELECT USER_ID FROM USERS WHERE ACCOUNT = ?
    • USER_ID:目标列
    • USERS:表名
    • ACCOUNT = ?:条件(?为占位符)

2. 核心组件

(1) 占位符(?)

  • 用于参数化查询,避免SQL注入
  • 执行时需绑定实际值:
    const queryArgs = ["user123"]; // 替换?的实际参数
    
(2) WHERE子句运算符
运算符 示例 说明
= ACCOUNT = ? 等于
LIKE NAME LIKE '%张%' 模糊匹配
IN ID IN (?,?,?) 多值匹配
BETWEEN AGE BETWEEN 18 AND 30 范围查询

3. 鸿蒙执行流程

  1. 获取RdbStore实例(数据库连接)
  2. 构建查询参数
    const predicates = new relationalStore.RdbPredicates("USERS"); // 表名
    predicates.equalTo("ACCOUNT", "user123"); // 条件设置
    
  3. 执行查询
    const resultSet = await rdbStore.query(predicates, ["USER_ID"]); // 指定返回列
    

4. 安全规范

  • 禁止拼接SQL
    ❌ 错误示例:SELECT ... WHERE ACCOUNT = '${userInput}'
    ✅ 正确做法:始终使用占位符?绑定参数
  • 列名/表名验证:动态名称需白名单过滤

5. 高级查询

-- 多表JOIN
SELECT u.USER_ID, o.ORDER_NO 
FROM USERS u 
JOIN ORDERS o ON u.ID = o.USER_ID
WHERE u.ACCOUNT = ?

-- 聚合函数
SELECT COUNT(*) FROM USERS WHERE AGE > 18

提示:完整文档见 HarmonyOS RDB开发指南(官方Gitee仓库)

经验2

在鸿蒙(HarmonyOS)的关系型数据库中清空数据表的所有数据后,通常需要手动重置主键自增计数器。以下是详细分析和操作建议,基于鸿蒙数据库的设计机制和最佳实践:

1. 为什么需要重置主键自增计数器?

  • 计数器不自动重置:鸿蒙的关系型数据库基于 SQLite 实现。当使用 DELETE 操作清空表数据时(例如 rdbStore.delete(predicates)),数据库仅移除数据行,但主键的自增计数器(如 AUTOINCREMENT)会保留最后一次插入的 ID 值。下次插入数据时,主键会从旧的最大值继续递增,可能导致主键冲突或不连续。
  • 潜在风险
    • 如果后续插入数据时主键值重复,会触发唯一性约束错误(错误码 14800011)。
    • 在数据同步或备份场景中,主键不连续可能影响数据一致性。

2. 如何重置主增计数器?
在鸿蒙开发中,需通过执行自定义 SQL 语句手动重置计数器。以下是具体方法(以 ArkTS 为例):

步骤 1:清空表数据

使用 RdbPredicates 删除所有数据:

import relationalStore from '@kit.RelationalStore';

// 假设 rdbStore 已初始化
let predicates = new relationalStore.RdbPredicates('your_table_name');
await rdbStore.delete(predicates); // 清空表数据
步骤 2:重置自增计数器

执行 SQL 语句重置计数器:

// 重置主键计数器(针对 SQLite 实现)
await rdbStore.executeSql("DELETE FROM sqlite_sequence WHERE name = 'your_table_name';");
  • 说明
    • sqlite_sequence 是 SQLite 的系统表,存储每个表的自增计数器值。
    • 执行此语句后,主键将从 1 重新开始计数。

3. 注意事项

  • 表是否定义自增主键:仅当表的主键使用了 AUTOINCREMENT 属性时(例如通过 @Column({ autoIncrement: true }) 注解),才需此操作。非自增主键无需重置。
  • 原子性操作:建议将清空数据和重置计数器放在事务中,确保操作原子性:
    await rdbStore.beginTransaction();
    try {
      await rdbStore.delete(predicates);
      await rdbStore.executeSql("DELETE FROM sqlite_sequence WHERE name = 'your_table_name';");
      await rdbStore.commit();
    } catch (err) {
      await rdbStore.rollback();
      console.error(`Operation failed: ${err.code}, ${err.message}`);
    }
    
  • 替代方案:如果表结构允许,可删除并重建表(通过 rdbStore.executeSql('DROP TABLE ...') 和重新初始化),但此方法更重,适用于表结构需变更的场景。

4. 使用第三方库的说明

如果使用 ZDbUtil 等第三方库(参考搜索结果中的库),其默认的 deletebatchDelete 操作不会自动重置计数器。需手动调用原生 executeSql 方法完成重置,或检查库是否提供扩展接口(如自定义 SQL 执行功能)。

总结

操作 是否必需 原因 推荐方法
清空表数据 移除所有数据行 rdbStore.delete(predicates)
重置自增计数器 避免主键冲突和连续性错误 rdbStore.executeSql("DELETE FROM sqlite_sequence WHERE name = 'table_name';")

通过手动重置计数器,可确保数据表在清空后保持正确的初始状态。如果涉及复杂业务逻辑(如数据同步),建议在鸿蒙的 relationalStore 模块文档中进一步查阅事务管理和错误处理机制。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐