发布时间:2026/7/11 9:37:50
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/7/11 9:37:50

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

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

2026/7/11 9:32:50

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

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

2026/7/11 11:38:18

droidVNC-NG:免ROOT远程控制Android设备的开源解决方案

droidVNC-NG:免ROOT远程控制Android设备的开源解决方案 【免费下载链接】droidVNC-NG Android VNC remote desktop server for local networks 项目地址: https://gitcode.com/gh_mirrors/dr/droidVNC-NG droidVNC-NG是一款基于现代Android 7 API构建的VNC服…

2026/7/11 11:38:18

AtomGit Flutter 鸿蒙客户端:Flutter 鸿蒙应用的错误处理与优雅降级策略

鸿蒙平台的不确定性比 Android/iOS 更大——你的错误处理需要更保守、更全面。 一、三层错误防护体系 ┌─────────────────────────────┐ │ 第1层:全局 Flutter 异常捕获 │ FlutterError.onError ├─────────────…

2026/7/11 11:38:18

交叉签名证书过期后,新的驱动签名要求

大多数交叉证书在 2021 年 7 月过期。 不能使用链接到过期交叉证书的代码签名证书为任何版本 Windows 创建新的内核模式数字签名。 驱动签名要求:EV代码签名证书 微软徽标认证 1、EV代码签名证书 代理商 2、微软徽标认证流程(whql) 代…

2026/7/11 11:38:18

C++一维数组深度解析:从内存模型到现代容器实践

1. 项目概述:为什么一维数组是C的基石如果你刚开始学C,或者已经写过一些代码,那么“数组”这个概念你一定不陌生。但你真的理解它吗?我见过太多新手,甚至一些工作一两年的朋友,对数组的理解还停留在“一个能…

2026/7/11 11:33:18

大模型智能体工程化实战:从崩溃到稳定的五级重构法则

1. 项目概述:从“崩溃”到“重构”的必经之路如果你正在用大模型API开发一个AI智能体,无论是客服机器人、数据分析助手,还是自动化流程引擎,那么“崩溃”这个词对你来说可能并不陌生。我说的崩溃,不是指程序运行时的异…

2026/7/11 5:30:49

国内大模型选型与企业级落地实战指南

我不能提供任何关于访问境外网络信息的技术方案或变通方法。根据中国法律法规和网络管理要求,所有互联网服务必须遵守国家关于网络安全、数据安全和内容安全的规定。ChatGPT及其后续版本(如所谓“GPT-5”)是由境外机构研发的大语言模型&#…

2026/7/11 2:43:05

三步实战方案:高效获取智慧教育平台电子课本PDF的完整流程

三步实战方案:高效获取智慧教育平台电子课本PDF的完整流程 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具,帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载,让您更方便地获取课本内容。 项目…

2026/7/11 8:37:53

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…