发布时间:2026/8/31 4:51:04
27 RdbPredicates 条件查询详解:EqualTo、OrderBy、组合条件 27 RdbPredicates 条件查询详解EqualTo、OrderBy、组合条件前言图27 RdbPredicates 条件查询详解EqualTo、OrderBy、组合条件 运行效果截图HarmonyOS NEXT在鸿蒙 RDB 中RdbPredicates是构建数据库查询条件的核心类。它提供了一套链式调用 API让开发者无需编写原始 SQL 即可完成复杂的条件组合。与直接拼接 SQL 相比RdbPredicates更安全、更可读、更易维护。本文以鹿鹿·笔迹心理分析项目中的 UserDao、HandwritingDao、ArchiveDao 等 DAO 代码为例全面解析 RdbPredicates 的各种条件构建方法。鸿蒙官方·RdbPredicates 文档developer.huawei.com项目源码仓库harmony-app GitHub图RdbPredicates 链式 API 分类——等值、范围、模糊、排序、分页RdbPredicates等值条件equalTo / notEqualTo范围条件greaterThan / lessThan / between模糊条件like / glob空值条件isNull / isNotNull排序分组orderByAsc / orderByDesc / groupBy分页限制limit / offset组合条件and / or / beginWrap / endWrap一、RdbPredicates 基础1.1 创建和基本用法RdbPredicates的构造函数接受一个参数——表名表示该谓词适用于哪张表importrelationalStorefromohos.data.relationalStore// 创建 predicates指定表名constpredicatesnewrelationalStore.RdbPredicates(handwriting)1.2 完整查询模式conststoreDatabaseService.getInstance().getStore()constpredicatesnewrelationalStore.RdbPredicates(TABLE)// ... 添加查询条件 ...constrsawaitstore.query(predicates,[col1,col2,...])二、常用查询条件2.1 等值查询// 最简单的等值条件predicates.equalTo(archive_id,archiveId)// SQL 等价WHERE archive_id ?predicates.equalTo(open_id,local)// SQL 等价WHERE open_id ?2.2 排序// 降序排列最新在前predicates.orderByDesc(created_at)// SQL 等价ORDER BY created_at DESC// 升序排列predicates.orderByAsc(created_at)// SQL 等价ORDER BY created_at ASC// 多字段排序predicates.orderByDesc(last_record_at)predicates.orderByDesc(id)// SQL 等价ORDER BY last_record_at DESC, id DESC2.3 区间查询// 不在 NULL 范围内的值predicates.isNotNull(archive_id)// SQL 等价WHERE archive_id IS NOT NULL// NULL 值predicates.isNull(archive_id)// SQL 等价WHERE archive_id IS NULL// 大于predicates.greaterThan(energy_score,50)// SQL 等价WHERE energy_score ?// 小于predicates.lessThan(word_count,100)// SQL 等价WHERE word_count ?// 范围predicates.between(created_at,startTime,endTime)// SQL 等价WHERE created_at BETWEEN ? AND ?// INpredicates.in(source,[camera,gallery])// SQL 等价WHERE source IN (?, ?)提示所有值都是参数化绑定?占位符不存在 SQL 注入风险。三、链式调用3.1 连续的链式调用// ArchiveDao.listByUserconstpredicatesnewrelationalStore.RdbPredicates(TABLE).equalTo(user_id,userId).orderByDesc(last_record_at)// SQL 等价WHERE user_id ? ORDER BY last_record_at DESC3.2 分步链式调用// HandwritingDao.listUnclassifiedconstpredicatesnewrelationalStore.RdbPredicates(TABLE)predicates.beginWrap()predicates.equalTo(archive_id,0)predicates.or()predicates.isNull(archive_id)predicates.endWrap()predicates.orderByDesc(created_at)// SQL 等价WHERE (archive_id 0 OR archive_id IS NULL) ORDER BY created_at DESC四、组合条件beginWrap / or / endWrap4.1 OR 组合// 查询未归类笔迹archive_id 0 或 archive_id IS NULLconstpredicatesnewrelationalStore.RdbPredicates(TABLE)predicates.beginWrap()predicates.equalTo(archive_id,0)// 条件 Apredicates.or()// ORpredicates.isNull(archive_id)// 条件 Bpredicates.endWrap()predicates.orderByDesc(created_at)// SQL 等价// WHERE (archive_id 0 OR archive_id IS NULL)// ORDER BY created_at DESC4.2 AND 组合默认行为如果不显式添加or()多个条件默认以AND连接constpredicatesnewrelationalStore.RdbPredicates(TABLE)predicates.equalTo(archive_id,archiveId)// 默认 ANDpredicates.orderByDesc(created_at)// SQL 等价WHERE archive_id ? ORDER BY created_at DESC// 实际上只有 1 个 WHERE 条件 1 个 ORDER BY4.3 嵌套条件// 复杂场景示例constpredicatesnewrelationalStore.RdbPredicates(TABLE)predicates.equalTo(user_id,userId)// user_id ?predicates.beginWrap()// (predicates.greaterThan(energy_score,60)// energy_score ?predicates.or()// ORpredicates.in(source,[camera,handwrite])// source IN (?, ?)predicates.endWrap()// )// SQL 等价// WHERE user_id ?// AND (energy_score ? OR source IN (?, ?))五、各 DAO 中的 RdbPredicates 应用汇总5.1 UserDao// findByOpenId —— 等值查询 单条结果constpredicatesnewrelationalStore.RdbPredicates(TABLE)predicates.equalTo(open_id,openId)// updateName —— 等值条件 updateconstpredicatesnewrelationalStore.RdbPredicates(TABLE)predicates.equalTo(id,id)awaitstore.update({name},predicates)5.2 HandwritingDao// findById —— 等值查询predicates.equalTo(id,id)// listByArchive —— 等值 排序predicates.equalTo(archive_id,archiveId)predicates.orderByDesc(created_at)// listUnclassified —— 组合条件ORpredicates.beginWrap()predicates.equalTo(archive_id,0)predicates.or()predicates.isNull(archive_id)predicates.endWrap()predicates.orderByDesc(created_at)// batchUpdateArchive —— 循环更新for(constidofids){constpredicatesnewrelationalStore.RdbPredicates(TABLE)predicates.equalTo(id,id)awaitstore.update({archive_id:archiveId},predicates)}5.3 ArchiveDao// listByUser —— 等值 排序predicates.equalTo(user_id,userId)predicates.orderByDesc(last_record_at)// findById —— 等值查询predicates.equalTo(id,id)// delete —— 等值条件删除predicates.equalTo(id,id)awaitstore.delete(predicates)5.4 各 DAO 的 RdbPredicates 使用统计DAOequalToorderByDescbeginWrap/or/endWrap用途UserDao✅❌❌用户查询HandwritingDao✅✅✅笔迹多条件查询ArchiveDao✅✅❌档案查询ReportDao✅✅❌报告查询RelationDao✅✅❌关系查询六、RdbPredicates vs 原始 SQL6.1 对比对比维度RdbPredicates原始 SQLquerySql类型安全✅ 方法名明确语义❌ 字符串拼接易错SQL 注入防护✅ 自动参数化绑定❌ 需手动?占位可读性✅ 链式调用清晰⚠️ 字符串较长时可读性差复杂查询JOIN❌ 不支持✅ 完全支持聚合函数❌ 不支持✅ COUNT / AVG / GROUP BY参数绑定自动需手动传 bindArgs6.2 选择建议// ✅ 用 RdbPredicates简单条件查询constpredicatesnewrelationalStore.RdbPredicates(TABLE)predicates.equalTo(archive_id,archiveId)predicates.orderByDesc(created_at)awaitstore.query(predicates,COLS)// ✅ 用原始 SQL聚合统计awaitstore.querySql(SELECT COUNT(*) AS cnt FROM handwriting WHERE archive_id ?,[archiveId])七、RdbPredicates 的完整 API方法用途SQL 等价项目中是否使用equalTo(field, value)等于WHERE field ?✅notEqualTo(field, value)不等于WHERE field ! ?❌greaterThan(field, value)大于WHERE field ?❌lessThan(field, value)小于WHERE field ?❌between(field, lo, hi)范围WHERE field BETWEEN ? AND ?❌in(field, values)INWHERE field IN (?, ?)❌notIn(field, values)NOT INWHERE field NOT IN (?, ?)❌isNull(field)为空WHERE field IS NULL✅isNotNull(field)非空WHERE field IS NOT NULL❌like(field, pattern)模糊WHERE field LIKE ?❌orderByAsc(field)升序ORDER BY field ASC❌orderByDesc(field)降序ORDER BY field DESC✅limit(count)限制行数LIMIT ?❌用 querySql 替代beginWrap()左括号(✅endWrap()右括号)✅or()OROR✅提示项目中主要使用equalTo、orderByDesc、beginWrap/or/endWrap这几种就覆盖了 90% 的查询场景。更复杂的统计查询直接使用原始 SQL。八、常见问题8.1 predicates 不能跨表// ❌ 错误RdbPredicates 只能作用于一张表constpredicatesnewrelationalStore.RdbPredicates(handwriting)// 无法同时查询 report 表的字段// ✅ 正确分两次查询或使用原始 SQL JOINconsthandwritingawaitHandwritingDao.findById(id)constreportawaitReportDao.findByHandwriting(handwriting.id!)8.2 每次查询创建新的 predicates// ✅ 正确每个方法内部创建新的 predicatesstaticasynclistByArchive(archiveId:number):PromiseHandwritingEntity[]{constpredicatesnewrelationalStore.RdbPredicates(TABLE)predicates.equalTo(archive_id,archiveId)// ...}// ❌ 错误复用 predicates 对象状态污染constglobalPredicatesnewrelationalStore.RdbPredicates(TABLE)总结本文全面解析了鸿蒙 RDB 中RdbPredicates的用法基础用法new RdbPredicates(TABLE) 条件方法 store.query(predicates, COLS)常用条件equalTo、orderByDesc、isNull覆盖了项目中 90% 的查询场景组合条件beginWrap()/or()/endWrap()构建 OR 嵌套链式调用方法链清晰表达查询意图与原始 SQL 互补简单查询用 RdbPredicates复杂聚合用 querySql下一篇文章将介绍ValuesBucket 数据插入——create 方法的 ValuesBucket 构建。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力参考资源RdbPredicates API 参考RdbStore.query 方法[UserDao 项目源码](file:///Users/fiona/Downloads/bijixinli/harmony-app/entry/src/main/ets/features/data/UserDao.ets)[HandwritingDao 项目源码](file:///Users/fiona/Downloads/bijixinli/harmony-app/entry/src/main/ets/features/data/HandwritingDao.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 开发文档七、RdbPredicates 与原始 SQL 对比对于项目中的查询需求RdbPredicates 和原始 SQL 各有适用场景场景RdbPredicates原始 SQL单表简单查询✅ 推荐链式可读可用但过于繁琐多条件组合✅ and/or 组合可用聚合统计COUNT/SUM❌ 不支持✅ 必须用 SQL多表 JOIN❌ 不支持✅ 必须用 SQL动态条件构建✅ 链式追加条件需要字符串拼接SQL 注入安全✅ 自动参数化需要手动参数绑定7.1 等效示例相同查询的两种写法对比// RdbPredicates 写法constprednewrelationalStore.RdbPredicates(handwriting)pred.equalTo(user_id,userId).orderByDesc(created_at).limit(10)constrsawaitstore.query(pred,[id,created_at,image_path])// 原始 SQL 写法constsqlSELECT id, created_at, image_path FROM handwriting WHERE user_id ? ORDER BY created_at DESC LIMIT 10constrs2awaitstore.querySql(sql,[userId])两种方式在功能上等效RdbPredicates 可读性更好SQL 方式更灵活。7.2 选择建议简单 CRUD 操作→ 优先使用 RdbPredicates代码更安全易读聚合统计、JOIN 查询→ 使用querySql原始 SQL动态多条件筛选→ RdbPredicates 链式调用更优雅复杂报表查询→ SQL 表达力更强直接写 SQL如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力

相关新闻

2026/8/29 10:05:11

IEEE 754 单精度浮点转换:3 种实现方案对比与内存布局解析

IEEE 754 单精度浮点转换:3 种实现方案对比与内存布局解析浮点数在计算机系统中的表示一直是底层开发者的必修课。当我们需要在调试器中查看内存数据,或在不同系统间传输二进制数据时,理解浮点数的内存布局至关重要。本文将深入解析IEEE 754单…

2026/8/31 4:31:45

游戏出海必看!APP推广必懂的ASO优化秘籍

无论你如何通过游戏盈利,获得更多下载量始终是增加收入的好方法,而自然增长(无需为每次下载付费)是实现这一目标的绝佳途径。在 App Store 和 Google Play 上的自然增长,来自于在搜索结果中的曝光度。这背后有着一套相…

2026/8/31 4:47:50

IDM下载加速全攻略:多线程下载设置与问题排查

1. 为什么我用浏览器下载总是很慢:IDM 到底解决什么问题很多朋友在日常工作中都有这样的体验:浏览器直接下载一个几十 MB 的安装包,速度忽快忽慢,中途断一下又要重新开始;想保存某个网页里的视频,右键检查半…

2026/8/31 4:47:50

【架构设计】2.9 系统性能

架构设计 相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 系统架构设计 相关文章: 【架构专栏】架构考试介绍 【架构专栏】架构知识点 知识总览​ 共19章内容,主要包括: 1)1绪论、2计算…

2026/8/31 4:47:50

直播录像处理实战:FFmpeg转码切片与批量归档全流程

分享一套直播录像文件处理实战教程,围绕直播回放视频的下载、转码、切片、字幕提取与文件管理完整流程展开。无论你是个人主播需要整理直播录像,还是运营同学要批量归档回放视频,都可以直接复用本文的脚本与命令。 特别说明:本文…

2026/8/31 4:47:50

【架构专栏】2.8 系统工程

架构设计 相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 系统架构设计 相关文章: 【架构专栏】架构考试介绍 【架构专栏】架构知识点 知识总览​ 共19章内容,主要包括: 1)1绪论、2计算…

2026/8/31 4:47:47

AI Native 降温背后:从工程实践看大模型落地的四个关键层

Meta 放弃“AI native”计划,相关传闻里还提到曾拟将部分团队裁员 60%。这则消息在开发者圈子里引发了大量讨论,但大多数讨论都停留在“Meta 是不是不行了”“AI 泡沫是不是要破了”这类二元判断上。我觉得真正值得关注的,不是某一家公司的战…

2026/8/31 4:42:47

Vibe Coding实战:从自然语言到可维护代码的完整工作流

最近一段时间,Vibe Coding 这个词几乎成了 AI 编程圈的新口头禅。我见过一个完全没写过 Python 的产品经理,在终端里用自然语言描述了一个 CSV 清洗脚本,AI 在一分钟内生成了代码,运行成功了。他非常兴奋,觉得自己可以…

2026/8/31 1:05:20

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/31 2:14:20

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/31 1:41:28

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/8/31 0:07:32

STM32C5设备支持包(IAR DFP)安装指南与常见坑

上一阵子在IAR里折腾一块基于STM32C5系列的新板子,工程从STM32CubeMX导出来之后怎么都编译不过。报错信息很干脆:找不到设备描述文件。跟着错误路径去查,发现指向的是一个让我愣了一下的名字:STMicroelectronics.stm32c5xx.2.1.0.…

2026/8/31 0:07:32

STM32N657 SWO引脚矛盾:CubeMX显示PB3,数据手册为PB5

拿到STM32N657这颗料的第一天,我就撞上了一个让人原地懵圈的引脚矛盾:CubeMX里清清楚楚显示SWO在PB3,翻开数据手册的引脚说明表,却赫然写着PB5。对于一个靠SWO输出调试日志吃饭的人而言,这种"工具和手册打架"…

2026/8/28 16:16:48

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/28 16:16:50

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/28 11:06:45

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…