28_ValuesBucket数据插入与实体映射 28 ValuesBucket 数据插入与实体映射前言图28 ValuesBucket 数据插入与实体映射 运行效果截图HarmonyOS NEXT在鸿蒙 RDB 中数据的插入通过store.insert(table, values)方法完成其中values的类型是ValuesBucket——本质上是一个键值对映射键是列名值是要插入的数据。本文将深入解析 ValuesBucket 的构建方法、实体→ValuesBucket 的映射模式以及项目 5 个 DAO 中 insert 操作的最佳实践。鸿蒙官方·ValuesBucket 文档developer.huawei.com项目源码仓库harmony-app GitHub图实体对象 → ValuesBucket → RDB Insert 完整流程ArkTS 实体对象Handwriting / UsertoValuesBucket 方法ValuesBucket键值对映射store.inserttableName, values返回 rowId新插入记录的 ID抛出异常插入失败一、ValuesBucket 基础1.1 定义ValuesBucket是一个类型别名本质上是Recordstring, number | string | boolean | Uint8Array | null// 类型定义typeValuesBucketRecordstring,number|string|boolean|Uint8Array|null// 最简单的使用constvalues:relationalStore.ValuesBucket{open_id:local,name:鹿鹿,created_at:Date.now()}1.2 值类型对照表ArkTS 类型ValuesBucket 类型插入到 SQL 中的类型GetternumbernumberINTEGER/REALgetLong()/getDouble()stringstringTEXTgetString()booleanbooleanINTEGER0/1getLong()Uint8ArrayUint8ArrayBLOBgetBlob()null/undefined不传或nullNULL判断后再读取二、各 DAO 的 ValuesBucket 构建2.1 UserDao最简单的插入// UserDao.ensureLocalUserconstvalues:relationalStore.ValuesBucket{open_id:local,name:name,// 方法参数传入created_at:Date.now()}constidawaitstore.insert(TABLE,values)特点只插入 3 个字段其余字段avatar有 DEFAULT 值或不填。2.2 HandwritingDao完整的字段映射staticasynccreate(item:HandwritingEntity):Promisenumber{conststoreHandwritingDao.getStore()constvalues:relationalStore.ValuesBucket{archive_id:item.archive_id??0,// ?? 处理可选字段source:item.source,// NOT NULL 字段image_path:item.image_path??,ocr_text:item.ocr_text??,feature_json:item.feature_json??,energy_score:item.energy_score??0,device_type:item.device_type??,word_count:item.word_count??0,write_duration:item.write_duration??0,created_at:item.created_at}returnawaitstore.insert(TABLE,values)}2.3 各 DAO 的 insert 映射对比DAO插入字段数必传字段可选字段处理UserDao3open_id, name, created_at不传SQL DEFAULTHandwritingDao10source, created_at??提供默认值ArchiveDao8user_id, name, created_at?? 或?? 0ReportDao7handwriting_id, created_at?? 或?? 0RelationDao5user_id, partner_archive_id, created_at?? 或?? 0三、字段默认值策略3.1 ?? 操作符的应用项目中大量使用??空值合并操作符来处理可选字段constvalues:relationalStore.ValuesBucket{archive_id:item.archive_id??0,// undefined → 0未归类image_path:item.image_path??,// undefined → 空字符串ocr_text:item.ocr_text??,feature_json:item.feature_json??,energy_score:item.energy_score??0,device_type:item.device_type??,// v2 新增字段word_count:item.word_count??0,write_duration:item.write_duration??0,}?? 与 || 的区别操作符false0undefinednulla ?? defaultfalse0defaultdefaulta || defaultdefaultdefaultdefaultdefaultdefault提示??只会在undefined或null时使用默认值。这对于数值字段如energy_score: 0非常重要——||会把0当作 falsy 值替换成默认值而??正确保留0。3.2 各字段类型的默认值SQL 类型ArkTS 类型ValuesBucket 默认值含义INTEGER (外键)number | undefined00 表示未关联INTEGER (数值)number | undefined0无数据TEXT (内容)string | undefined空字符串TEXT (路径)string | undefined无路径INTEGER (NOT NULL)number必传无默认值必须传入有效值四、insert 的返回值4.1 返回值说明constidawaitstore.insert(TABLE,values)// 返回值类型number// 成功时新插入行的 row ID自增主键值// 失败时抛出异常4.2 典型用法// HandwritingDao.create — 返回 ID供后续创建报告使用consthandwritingIdawaitHandwritingDao.create({archive_id:archiveId,source:camera,ocr_text:ocrText,feature_json:JSON.stringify(features),created_at:Date.now()})// 使用返回的 ID 创建关联报告awaitReportDao.create({handwriting_id:handwritingId,archive_id:archiveId,personality_type:result.type,radar_json:JSON.stringify(result.scores),created_at:Date.now()})五、预置的 ValuesBucket 模式5.1 直接字面量// UserDao — 简单字段少constidawaitstore.insert(TABLE,{open_id:local,name,created_at:Date.now()})5.2 从 Entity 映射// HandwritingDao — 从 HandwritingEntity 对象映射constvalues:relationalStore.ValuesBucket{archive_id:item.archive_id??0,source:item.source,image_path:item.image_path??,// ...}5.3 手动构造// DemoSeeder — 在循环中构造consthandwritingIdawaitHandwritingDao.create({archive_id:archiveId,source:demo,image_path:,ocr_text:p.text,feature_json:JSON.stringify(p.scores),energy_score:p.scores.energy,created_at:timestamp})六、写入性能优化建议6.1 批量插入当需要插入多条记录时逐条insert效率较低// ❌ 逐条插入DemoSeeder 中目前的方式for(constitemofitems){awaitHandwritingDao.create(item)}// ✅ 批量插入优化使用事务staticasyncbatchCreate(items:HandwritingEntity[]):Promisevoid{conststoreHandwritingDao.getStore()awaitstore.executeSql(BEGIN TRANSACTION)try{for(constitemofitems){constvalues:relationalStore.ValuesBucket{/* ... */}awaitstore.insert(TABLE,values)}awaitstore.executeSql(COMMIT)}catch(e){awaitstore.executeSql(ROLLBACK)throwe}}6.2 事务性能对比方式插入 10 条插入 100 条说明逐条插入无事务~50ms~500ms每条 commit 一次显式事务~5ms~30ms一次 commit批量 prepareSQLite~3ms~20ms最优化七、常见错误排查7.1 字段名不匹配// ❌ 错误字段名拼写错误constvalues:relationalStore.ValuesBucket{create_at:Date.now()// 拼写错误应该是 created_at}// SQLite 会静默忽略不存在的列名// ✅ 正确与 CREATE TABLE 中的列名完全一致constvalues:relationalStore.ValuesBucket{created_at:Date.now()}7.2 NOT NULL 约束冲突// ❌ 错误NOT NULL 字段没有传入constvalues:relationalStore.ValuesBucket{}awaitstore.insert(TABLE,values)// → 抛出异常NOT NULL constraint failed: user.name// ✅ 正确所有 NOT NULL 字段都有值constvalues:relationalStore.ValuesBucket{source:camera,created_at:Date.now()}7.3 类型不匹配// ❌ 错误类型不匹配constvalues:relationalStore.ValuesBucket{name:12345// SQL 中 name 是 TEXT但传了 number}// ✅ 正确类型一致constvalues:relationalStore.ValuesBucket{name:鹿鹿// string → TEXT}八、协议层映射总结8.1 数据的完整生命周期// ① ArkTS 页面得到用户输入constcapturedText今天醒得很早...// ② 构造 Entity 对象constentity:HandwritingEntity{archive_id:1,source:camera,ocr_text:capturedText,created_at:Date.now()}// ③ Entity → ValuesBucketDAO 层constvalues:relationalStore.ValuesBucket{/* ... */}// ④ ValuesBucket → RDB 存储constidawaitstore.insert(handwriting,values)// ⑤ 数据库存储 → 界面呈现翻到下一篇文章)// store.query → ResultSet → Entity → UI总结本文深入解析了鸿蒙 RDB 中 ValuesBucket 的使用方法定义ValuesBucket Recordstring, number | string | boolean | Uint8Array | null映射模式Entity 对象 → ValuesBucket??操作符处理可选字段字段默认值外键未关联→0文本不存在→数值不存在→0返回值insert返回自增主键 id可立即用于关联表插入事务优化批量插入时使用显式事务提升性能常见错误字段名拼写、NOT NULL 约束、类型不匹配下一篇文章将介绍ResultSet 结果集遍历与解析——从数据库查询结果到 Entity 对象的完整转换。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力参考资源ValuesBucket API 参考RdbStore.insert 方法[HandwritingDao 项目源码](file:///Users/fiona/Downloads/bijixinli/harmony-app/entry/src/main/ets/features/data/HandwritingDao.ets)[UserDao 项目源码](file:///Users/fiona/Downloads/bijixinli/harmony-app/entry/src/main/ets/features/data/UserDao.ets)[ArchiveDao 项目源码](file:///Users/fiona/Downloads/bijixinli/harmony-app/entry/src/main/ets/features/data/ArchiveDao.ets)[ReportDao 项目源码](file:///Users/fiona/Downloads/bijixinli/harmony-app/entry/src/main/ets/features/data/ReportDao.ets)[RelationDao 项目源码](file:///Users/fiona/Downloads/bijixinli/harmony-app/entry/src/main/ets/features/data/RelationDao.ets)鸿蒙数据持久化指南HarmonyOS 开发文档七、ValuesBucket 常见问题与最佳实践7.1 字段名大小写ValuesBucket 的键名必须与数据库中的列名完全一致区分大小写// ✅ 正确与 CREATE TABLE 中的列名一致values[user_id]data.userId values[created_at]data.createdAt// ❌ 错误大小写不匹配values[userId]data.userId// 数据库中是 user_idvalues[CreatedAt]data.createdAt// 数据库中是 created_at7.2 undefined vs null 的处理ValuesBucket 不接受undefined可选字段必须显式设为null// ✅ 正确可选字段用 nullvalues[partner_id]data.partnerId??null// ❌ 错误undefined 会导致插入异常values[partner_id]data.partnerId// 如果 partnerId 未定义会报错7.3 数值类型选择ArkTS 类型ValuesBucket 赋值类型数据库存储类型numbernumberINTEGER / REALstringstringTEXTbooleannumber (0/1)INTEGERobject / arrayJSON.stringify(obj)TEXTDatedate.toISOString()TEXT7.4 批量插入优化使用事务批量插入比逐条插入性能提升显著// 批量插入 —— 使用事务asyncfunctionbatchCreate(records:Handwriting[]):Promisevoid{conststoreDatabaseService.getInstance().getStore()awaitstore.beginTransaction()try{for(constrecordofrecords){constvalues:relationalStore.ValuesBucket{}values[id]record.id values[user_id]record.userId values[created_at]record.createdAtawaitstore.insert(handwriting,values)}awaitstore.commit()}catch(err){awaitstore.rollBack()throwerr}}如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力

相关新闻

最新新闻

皮尔逊、斯皮尔曼、肯德尔相关系数全解析:原理、选择与实战避坑指南

皮尔逊、斯皮尔曼、肯德尔相关系数全解析:原理、选择与实战避坑指南

1. 项目概述:从“有关系”到“有多相关” 在数据分析、金融风控、社会科学乃至我们日常的决策中,一个高频出现的问题是:这两个变量之间,到底有没有关系?如果有,关系有多强?是正相关还是负相关&a…

2026/8/29 11:31:39
STM32 ADC从原理到实战:多通道、DMA与滤波算法全解析

STM32 ADC从原理到实战:多通道、DMA与滤波算法全解析

1. 项目概述:为什么ADC是嵌入式开发的“感官”核心? 玩过STM32的朋友都知道,光会点个灯、调个串口,那只是入门。想让你的单片机真正“感知”世界,ADC(模数转换器)是绕不开的一道坎。无论是测量电…

2026/8/29 11:31:39
评审工具选型看团队流程

评审工具选型看团队流程

评审工具选型看团队流程 讨论“评审工具选型看团队流程”时,最容易出现的偏差是先给方案,再补问题定义。团队决策与工程协作里,同一个实现放到不同负载、不同依赖版本或不同操作路径下,结果可能完全不同。更稳妥的起点&#xff0c…

2026/8/29 11:31:39
架构发布前的可执行核对

架构发布前的可执行核对

架构发布前的可执行核对不少方案在演示环境里显得顺畅,进入多人协作或长期运行后才暴露问题。“架构发布前的可执行核对”关注的正是这段落差。对服务部署与分布式调用链路而言,可维护的实现不靠一句“已经处理异常”,而靠清楚的触发条件、可…

2026/8/29 11:31:39
图算法服务限制状态空间

图算法服务限制状态空间

图算法服务限制状态空间把“图算法服务限制状态空间”做扎实,先要放下对工具和框架的偏好,回到实际任务。数据处理与查询链路中的许多返工,并非某个组件能力不足,而是输入、状态和责任没有说透。文档如果只写正常流程,…

2026/8/29 11:31:39
Hoppscotch 浏览器扩展完整指南:三步装好,快速搞定本地接口调试

Hoppscotch 浏览器扩展完整指南:三步装好,快速搞定本地接口调试

Hoppscotch 浏览器扩展完整指南:三步装好,快速搞定本地接口调试 【免费下载链接】hoppscotch Open-Source API Development Ecosystem • https://hoppscotch.io • Offline, On-Prem & Cloud • Web, Desktop & CLI • Open-Source Alternative…

2026/8/29 11:26:39