AI陪伴机器人Repository派生查询-八个接口零SQL
04-Repository派生查询-八个接口零SQL黒漂技术佬 · AI 伙伴AI-Partner「数据接口部署与二次开发」系列 04上一系列讲完实体这篇看数据访问层。AI 伙伴的 repository 包里有 8 个接口全部继承JpaRepository加起来 22 个查询方法——没有一行 SQL没有一个 Query 注解。查询全靠方法名自己会说话的派生查询Derived Query。这篇把这套命名语法彻底拆开让你以后看到方法名就知道它翻译成什么 SQL。一、先看一个最短的例子// 项目源码repository/UserRepository.javapublicinterfaceUserRepositoryextendsJpaRepositoryUser,Long{OptionalUserfindByOpenId(StringopenId);OptionalUserfindByPhone(Stringphone);}就这么两行。Spring Data JPA 在启动时解析方法名findByOpenIdfindBy是关键字前缀OpenId对应实体属性openId自动生成select * from t_user where open_id ?。返回OptionalUser表示可能查不到。其他 7 个 Repository 同理全是这个玩法。二、派生查询命名语法完整拆解方法名 关键词 属性表达式 排序子句关键词之间可以自由组合。下面这张表把本项目用到的全部关键词列齐关键词语义项目实例findBy查询等值条件findByOpenIdcountBy计数countByUserIdAndActiveTrueAnd条件连接ANDfindByUserIdAndActiveTrueAndContentContainingOrderBy...Desc/Asc排序OrderByImportanceDescCreatedAtDescBetween区间含边界findByUserIdAndRecordedAtBetween...After/LessThanEqual大于 / 小于等于AndRecordedAtAfter、RemindTimeLessThanEqualContainingLIKE ‘%xxx%’AndContentContainingIsTrueActiveTrue布尔 trueActiveTrueTopN取前 N 条findTop10ByUserId...、findTop20ByUserId...Pageable参数分页findByUserIdOrderByCreatedAtDesc(Long, Pageable)几个容易犯迷糊的点Containing是两边带 % 的模糊匹配生成content LIKE %关键词%。项目用它做记忆的关键词检索。Between是闭区间两端都含传now().minusDays(7)和now()就是近 7 天含今天。TopN放在 findBy 后面findTop10ByUserIdOrderByRecordedAtDescORDER BY recorded_at DESC LIMIT 10。Pageable是参数不是方法名的一部分方法名照常写加一个Pageable形参即可分页返回类型可以是ListT或PageT。对话历史查询就是findByUserIdOrderByCreatedAtDesc(Long userId, Pageable pageable)。排序可以多级OrderByImportanceDescCreatedAtDesc 先按重要度降序重要度相同再按创建时间降序。三、八个 Repository 方法清单逐个过Repository方法业务用途与 SQL 语义UserRepositoryfindByOpenId(String)登录即查找按平台 openId 找用户找不到就注册findByPhone(String)按手机号找回用户MemoryItemRepositoryfindByUserIdAndActiveTrueOrderByImportanceDescCreatedAtDesc本项目的灵魂查询取该用户未删除的记忆重要度优先、新记忆优先用于注入 Agent 系统提示词前 20 条findByUserIdAndActiveTrueAndTypeOrderByCreatedAtDesc(Long, String)按记忆类型fact/preference/relation/event/health过滤查看findByUserIdAndActiveTrueAndContentContaining(Long, String)关键词搜记忆countByUserIdAndActiveTrue(Long)记忆条数统计ReminderRepositoryfindByUserIdAndStatusOrderByRemindTimeAsc(Long, String)用户待触发提醒列表按触发时间升序最近的排最前findByStatusAndRemindTimeLessThanEqualAndPushedFalse(String, LocalDateTime)定时任务专用扫pending 且 remindTime ≤ 当前且未推送的到期提醒每分钟执行一次findByUserId(Long)用户全部提醒ConversationRepositoryfindByUserIdOrderByCreatedAtDesc(Long, Pageable)分页拉对话历史新的在前countByUserId(Long)对话总轮数EmotionRecordRepositoryfindByUserIdAndRecordedAtBetweenOrderByRecordedAtDesc(Long, LocalDateTime, LocalDateTime)时间段情绪记录做情绪趋势findTop10ByUserIdOrderByRecordedAtDesc(Long)最近 10 条情绪Agent 查用户最近心情用HealthRecordRepositoryfindByUserIdAndTypeAndRecordedAtBetweenOrderByRecordedAtDesc(Long, String, LocalDateTime, LocalDateTime)近 7 天某类健康数据趋势心率/血压曲线的底层findTop20ByUserIdOrderByRecordedAtDesc(Long)最近 20 条健康记录findByUserIdAndAbnormalTrueAndRecordedAtAfter(Long, LocalDateTime)某时间之后的异常记录健康巡检用DeviceRepositoryfindByDeviceCode(String)按设备编码查设备注册、绑定、下发指令的入口查询findByUserId(Long)用户绑定设备列表findByStatus(String)/countByStatus(String)按在线状态筛设备 / 统计在线数AlertRepositoryfindByStatusOrderByCreatedAtDesc(String)全部待处理工单新的在前findByUserIdAndStatusOrderByCreatedAtDesc(Long, String)某用户的工单列表可以观察到一条规律每个方法的形态都精确对应一个业务场景。Agent 拼 prompt要重要度排序就写OrderByImportanceDesc定时扫到期要时间比较加未推送过滤就写LessThanEqual加PushedFalse。方法名不是随手起的是需求直接翻译。四、为什么这个项目不需要 QueryQuery用来手写 JPQL 或原生 SQL适合派生查询表达不了的场景。AI 伙伴全部查询能靠方法名搞定根本原因是所有查询都是单表、等值/区间/排序/取前的组合没有跨表 JOIN没有复杂聚合。这又回到了第一篇说的无外键、实体零关联的设计——既然实体互不引用就永远不需要 JOIN派生查询的舒适区就永远够用。这是个漂亮的自洽表设计决定了查询形态查询形态决定了数据访问层的写法。你二次开发时如果延续单表职责、逻辑关联的风格就能继续享受零 SQL一旦打破就得换工具。五、派生查询的边界什么时候该换写法四种情况派生查询会开始吃力多表 JOIN比如查所有今天触发过跌倒告警的用户及其设备名跨t_alert和t_device方法名写不出来老老实实Query写 JPQL join或者拆成两次单表查询在 Service 里组装。复杂聚合GROUP BY type HAVING COUNT(*) 5这类统计方法名无能为力。动态条件查询条件由前端传参决定可选 userId、可选 status、可选时间段方法名组合爆炸。此时该上Specification或QueryDSL。性能敏感的批量操作Modifying Query批量 UPDATE/DELETE 比逐条 save 快得多。拿本项目举个反例也能说明问题EmotionService.recent想查最近 N 条情绪但 Repository 只定义了findTop10ByUserIdOrderByRecordedAtDesc固定取 10 条——Controller 传的 limit 参数实际是取回来后在内存里截断的。这就是派生查询参数化 LIMIT不方便的缩影不如一个Query(select e from EmotionRecord e where e.userId:uid order by e.recordedAt desc)配Pageable来得干脆。六、命名过长的可读性权衡findByUserIdAndActiveTrueOrderByImportanceDescCreatedAtDesc——56 个字符的方法名初见吓一跳。但换个角度它把查询意图完整写在了签名里IDE 补全一敲就出来review 代码时不用跳到 SQL 里猜语义。我个人觉得这比getUserMemoriesV2()这种黑盒命名诚实得多。权衡建议方法名控制在能读出查什么、按什么过滤、怎么排序的程度超过三个 And 条件就考虑加注释说明业务含义五个以上就该怀疑是不是该换 Query 了。七、可运行的验证方式打开 show-sql想知道每个方法名翻译成了什么 SQL最直接的办法是把show-sql打开跑一遍# application.yml 开发环境临时调整spring:jpa:show-sql:trueproperties:hibernate:format_sql:true然后启动后端调一次接口如POST /api/chat让 Agent 查记忆控制台就能看到生成语句-- 示意Hibernate 实际输出字段有删节select...fromt_memorywhereuser_id?andactive1orderbyimportancedesc,created_atdesc;对照方法名逐段核对UserId→user_id?、ActiveTrue→active1、OrderByImportanceDescCreatedAtDesc→order by importance desc, created_at desc。验完记得关掉 show-sql别把调试开关带上线。八、合规提醒记忆、情绪、健康三个 Repository 的查询结果都会拼进大模型的提示词等于把用户的敏感数据交给外部大模型服务处理。二次开发扩展查询时注意查询粒度最小化不要一次捞全量历史、在日志里脱敏show-sql 打开时对话和健康数据会打进日志生产环境严禁、返回给前端前做权限校验只能查当前授权用户自己的数据。小结派生查询是把查询需求直接写进方法名的声明式风格——单表、简单条件时它是最优雅的选择AI 伙伴 8 个 Repository、22 个方法、零 SQL 就是最有力的示范。但它的舒适区有明确边界JOIN、聚合、动态条件一旦出现就该请 Query 和 Specification 出山。下一篇我们站到接口层看 9 个 Controller 是怎么把这套数据能力组织成 20 个 HTTP 接口的。

相关新闻

AI陪伴机器人API设计-api-users到api-alerts的二十个接口

AI陪伴机器人API设计-api-users到api-alerts的二十个接口

05-API设计-api-users到api-alerts的二十个接口黒漂技术佬 AI 伙伴(AI-Partner)「数据接口部署与二次开发」系列 05数据层拆完了,这篇上到接口层。AI 伙伴后端一共 9 个 Controller、19 个 HTTP 接口,全部基于 http://localhost:…

2026/9/24 4:03:53 阅读更多 →
SSM毕设项目:基于 SSM 的视频课程资源管理系统的设计与实现 基于 SSM 的在线学习资源推送系统 (源码+文档,讲解、调试运行,定制等)

SSM毕设项目:基于 SSM 的视频课程资源管理系统的设计与实现 基于 SSM 的在线学习资源推送系统 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/24 4:03:53 阅读更多 →
GitHub趋势榜解读:从打不开到跑起来的全能实战指南

GitHub趋势榜解读:从打不开到跑起来的全能实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 4:03:53 阅读更多 →

最新新闻

黄金微针按次报价怎样核对包含项和变更差价

黄金微针按次报价怎样核对包含项和变更差价

黄金微针写着“按次收费”,并不自动说明一次包括哪些内容。到了比较报价或调整方案时,真正影响支出的,是服务范围怎样变化、原付款有多少可以用于新方案,以及哪些款项仍在单独处理中。先统一口径,再算差额,…

2026/9/24 4:50:28 阅读更多 →
国产安全MCU LKT6830C开发实战:硬件加密与防篡改设计

国产安全MCU LKT6830C开发实战:硬件加密与防篡改设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 4:50:28 阅读更多 →
Storm 安全加固:Kerberos 认证、ACL 权限与多租户隔离

Storm 安全加固:Kerberos 认证、ACL 权限与多租户隔离

Storm 安全加固:Kerberos 认证、ACL 权限与多租户隔离Apache Storm 作为分布式实时计算框架,广泛应用于实时数据处理场景。随着企业级应用的需求增长,Storm 平台的安全性也日益重要。本文将详细介绍 Storm 安全加固的三大核心机制&#xff1a…

2026/9/24 4:50:28 阅读更多 →
Flutter鸿蒙化适配:screen_protector防截屏插件ArkTS实现指南

Flutter鸿蒙化适配:screen_protector防截屏插件ArkTS实现指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 4:50:28 阅读更多 →
RK3506 AMP双系统实战:Linux+FreeRTOS核间通信与实时性优化

RK3506 AMP双系统实战:Linux+FreeRTOS核间通信与实时性优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 4:50:28 阅读更多 →
CodeBurn 发布验收 Agent 执行手册:从候选 SHA 到 release-ready 的可复现审计契约

CodeBurn 发布验收 Agent 执行手册:从候选 SHA 到 release-ready 的可复现审计契约

【免费下载链接】codeburn Free, local tool to track AI coding token usage and cost across 37 tools and agents (Claude Code, Cursor, Codex, Gemini and more), by model, project, and task. npx codeburn 项目地址: https://gitcode.com/gh_mirrors/co/cod…

2026/9/24 4:49:27 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →