开发规范

CRUD / Query 开发主路径

按能力组合创建、更新、查询和扩展条件,保持生命周期一致。

浏览全部手册
本页目录
文档来源与 Markdown 原文

权威正文:ineed-core/docs/project-development/crud-query-guide.md。网站按工作区快照同步,原文中的历史日期和验证范围保留。

开始编码前核对同版本源码;跨仓文件引用可在源码定位目录查找。

下载 Markdown 原文 ↓

适用范围

本文档覆盖 Ineed-Core 当前两条开发主链路:

  • 阻塞式WebMvc + JPA/JDBC/MyBatis-Flex
  • 响应式WebFlux + R2DBC

阻塞式链路是当前优先推荐的验收基线;响应式链路作为对等能力线同步维护。新业务模块、公共能力或代码生成任务,如果需求没有明确限定单线实现,应同时评估并对齐两条线。

标准主路径

两条链路共享同一分层架构:

Controller -> Service -> Manager -> Repository/EntityManager

层次 阻塞式模块 响应式模块 职责
Web 入口 ineed-core-webmvc ineed-core-webflux 对外暴露 API、参数校验、统一返回
业务编排 ineed-core-engine ineed-core-engine-reactive 事务边界、业务编排、桥接 Manager
业务能力 ineed-core-engine ineed-core-engine-reactive 单类实体规则、CRUD、查询、状态切换
数据访问 ineed-core-data-jpa/jdbc/mybatis-flex ineed-core-data-r2dbc 持久化与查询执行

标准能力入口总览

以下能力按需组合,只有业务对象具备对应能力时才实现对应接口。

能力 WebMvc Controller WebFlux Controller Service Manager 说明
创建 ICreateController ICreateController ICreateService ICreateManager 单条与批量创建
更新 IUpdateController IUpdateController IUpdateService IUpdateManager AO.id 更新
按 ID 查询 IFindByIdController IFindByIdController IFindByIdService IFindByIdManager 单 ID 与批量 ID 查询
分页查询 ISearchController ISearchController ISearchService ISearchManager 标准 CommonParameters + Query
回收站查询 ISearchRecycleController ISearchRecycleController ISearchRecycleService ISearchRecycleManager 查询已逻辑删除数据
逻辑删除与恢复 ILogicDeleteController ILogicDeleteController ILogicDeleteService ILogicDeleteManager 单/批量逻辑删除、恢复
物理删除 IPhysicsDeleteController IPhysicsDeleteController IPhysicsDeleteService IPhysicsDeleteManager 单/批量物理删除;forceDelete 无标准 Web 入口
字典查询 ISearchDictionaryController ISearchDictionaryController ISearchDictionaryService ISearchDictionaryManager 返回 DictionaryValue
树查询 ISearchTreeController 同左 ISearchTreeService ISearchManager 返回树节点,query.lazyLoad=true 时按父节点懒加载
树字典查询 ISearchDictionaryTreeController 同左 ISearchDictionaryTreeService ISearchManager 返回字典树
按主对象查询 ISearchOfMasterIdController 同左 ISearchOfMasterIdService IFindByIdManager + ISearchManager 先查主对象再查关联列表
按主对象字典查询 ISearchDictionaryOfMasterIdController 同左 ISearchDictionaryOfMasterIdService IFindByIdManager + ISearchDictionaryManager 主对象关联字典查询
按主对象字典树查询 ISearchDictionaryTreeOfMasterIdController 同左 ISearchDictionaryTreeOfMasterIdService IFindByIdManager + ISearchManager 主对象关联字典树查询
数据状态 IEnableController / ILockController / IPublishController / IDefaultController / IPrimaryController 同左 对应 *Service 对应 *Manager 单/批量状态切换
排序 IOrderController IOrderController IOrderService IOrderManager moveBefore/After/Top/Bottom
重复校验 IDuplicateController IDuplicateController IDuplicateService IDuplicateManager 创建/更新场景重复检查
账户动作 IAccountController IAccountController IAccountService IAccountManager 重置密码、启用、禁用、锁定、解锁

CRUD 入口矩阵

所有路径相对于业务 Controller 根路径。权限后缀两条线一致。

能力 HTTP 路径 权限后缀 WebMvc 返回 WebFlux 返回
单条创建 POST 根路径 create ResponseResults<V> Mono<ResponseResults<V>>
批量创建 POST /batch batch-create ResponseResults<Iterable<V>> Mono<ResponseResults<Iterable<V>>>
更新 PUT 根路径 update ResponseResults<V> Mono<ResponseResults<V>>
逻辑删除 DELETE /{id} logic-delete ResponseResults<Void> Mono<ResponseResults<Void>>
批量逻辑删除 DELETE /batch/logic-delete batch-logic-delete ResponseResults<Void> Mono<ResponseResults<Void>>
恢复 PUT /recovery/{id} recovery ResponseResults<Void> Mono<ResponseResults<Void>>
批量恢复 PUT /recovery batch-recovery ResponseResults<Void> Mono<ResponseResults<Void>>
物理删除 DELETE /physics/{id} physics-delete ResponseResults<Void> Mono<ResponseResults<Void>>
批量物理删除 DELETE /batch/physics-delete batch-physics-delete ResponseResults<Void> Mono<ResponseResults<Void>>

forceDelete(id / idSet) 只存在于 IPhysicsDeleteService / IPhysicsDeleteManager,标准 Controller 未暴露入口。业务如需开放强制删除,必须显式定义自定义接口和权限点。

查询入口矩阵

能力 HTTP 路径 WebMvc 返回 WebFlux 返回
分页查询 GET 根路径 ResponseResults<QueryResults<V>> Mono<ResponseResults<QueryResults<V>>>
按 ID 查询 GET /{id} ResponseResults<V> Mono<ResponseResults<V>>
批量按 ID 查询 GET /batch?idSet=... ResponseResults<Iterable<V>> Mono<ResponseResults<Iterable<V>>>
回收站查询 GET /recycle ResponseResults<QueryResults<V>> Mono<ResponseResults<QueryResults<V>>>
字典查询 GET /dictionary ResponseResults<QueryResults<DictionaryValue>> Mono<ResponseResults<QueryResults<DictionaryValue>>>
树查询 GET /tree ResponseResults<QueryResults<TN>> Mono<ResponseResults<QueryResults<TN>>>
树字典查询 GET /tree/dictionary ResponseResults<QueryResults<DictionaryValueTreeNode>> Mono<ResponseResults<QueryResults<DictionaryValueTreeNode>>>
按主对象查询 GET /of/{masterId} ResponseResults<MasterQueryResults<M, V>> Mono<ResponseResults<MasterQueryResults<M, V>>>
按主对象字典查询 GET /dictionary/of/{masterId} ResponseResults<QueryResults<DictionaryValue>> Mono<ResponseResults<QueryResults<DictionaryValue>>>
按主对象字典树查询 GET /tree/dictionary/of/{masterId} ResponseResults<MasterQueryResults<M, DictionaryValueTreeNode>> Mono<ResponseResults<MasterQueryResults<M, DictionaryValueTreeNode>>>

查询类标准 Controller 默认方法没有接口级 @PreAuthorize。如果业务模块要在权限清单中登记查询 API 权限,应按 frontend-integration-guide.md 生成 api 节点。

数据状态、排序、重复和账户入口矩阵

能力 HTTP 路径 权限后缀 WebMvc 返回 WebFlux 返回
启用 PUT /enable/{id} enable ResponseResults<Void> Mono<ResponseResults<Void>>
批量启用 PUT /enable batch-enable ResponseResults<Void> Mono<ResponseResults<Void>>
禁用 PUT /disable/{id} disable ResponseResults<Void> Mono<ResponseResults<Void>>
批量禁用 PUT /disable batch-disable ResponseResults<Void> Mono<ResponseResults<Void>>
锁定 PUT /lock/{id} lock ResponseResults<Void> Mono<ResponseResults<Void>>
批量锁定 PUT /lock batch-lock ResponseResults<Void> Mono<ResponseResults<Void>>
解锁 PUT /unlock/{id} unlock ResponseResults<Void> Mono<ResponseResults<Void>>
批量解锁 PUT /unlock batch-unlock ResponseResults<Void> Mono<ResponseResults<Void>>
发布 PUT /publish/{id} publish ResponseResults<Void> Mono<ResponseResults<Void>>
批量发布 PUT /publish batch-publish ResponseResults<Void> Mono<ResponseResults<Void>>
撤销发布 PUT /withdraw/{id} withdraw ResponseResults<Void> Mono<ResponseResults<Void>>
批量撤销发布 PUT /withdraw batch-withdraw ResponseResults<Void> Mono<ResponseResults<Void>>
设为默认 PUT /default/{id} default ResponseResults<Void> Mono<ResponseResults<Void>>
批量设为默认 PUT /default batch-default ResponseResults<Void> Mono<ResponseResults<Void>>
取消默认 PUT /non-default/{id} non-default ResponseResults<Void> Mono<ResponseResults<Void>>
批量取消默认 PUT /non-default batch-non-default ResponseResults<Void> Mono<ResponseResults<Void>>
设为主要 PUT /primary/{id} primary ResponseResults<Void> Mono<ResponseResults<Void>>
批量设为主要 PUT /primary batch-primary ResponseResults<Void> Mono<ResponseResults<Void>>
取消主要 PUT /non-primary/{id} non-primary ResponseResults<Void> Mono<ResponseResults<Void>>
批量取消主要 PUT /non-primary batch-non-primary ResponseResults<Void> Mono<ResponseResults<Void>>
移到目标前 PUT /order/before order ResponseResults<V> Mono<ResponseResults<V>>
移到目标后 PUT /order/after order ResponseResults<V> Mono<ResponseResults<V>>
移到顶部 PUT /order/top order ResponseResults<V> Mono<ResponseResults<V>>
移到底部 PUT /order/bottom order ResponseResults<V> Mono<ResponseResults<V>>
创建重复校验 POST /duplicate duplicate ResponseResults<Boolean> Mono<ResponseResults<Boolean>>
更新重复校验 PUT /duplicate duplicate ResponseResults<Boolean> Mono<ResponseResults<Boolean>>
重置账户密码 PUT /account/passwd/reset/{id} account-passwd-reset ResponseResults<Void> Mono<ResponseResults<Void>>
禁用账户 PUT /account/disable/{id} account-disable ResponseResults<Void> Mono<ResponseResults<Void>>
启用账户 PUT /account/enable/{id} account-enable ResponseResults<Void> Mono<ResponseResults<Void>>
锁定账户 PUT /account/lock/{id} account-lock ResponseResults<Void> Mono<ResponseResults<Void>>
解锁账户 PUT /account/unlock/{id} account-unlock ResponseResults<Void> Mono<ResponseResults<Void>>

数据状态能力由实体 DataStatusFeature 决定,不应默认全开。实体没有对应能力时不生成对应 Controller / Service / Manager。

CRUD 接入步骤

1. 定义 Web 层入口

阻塞式入口位于 ineed-core-webmvc,响应式入口位于 ineed-core-webflux,围绕以下接口展开:

  • ICreateController / IUpdateController / ILogicDeleteController / IPhysicsDeleteController

2. 定义 Service 层桥接

  • ICreateService / IUpdateService / ILogicDeleteService / IPhysicsDeleteService

通过 getManager() 暴露 Manager,通过 ServiceSupport.requireManager(...) 调用具体能力。

3. 定义 Manager 层能力

  • ICreateManager / IUpdateManager / ILogicDeleteManager / IPhysicsDeleteManager

具体数据栈实现在对应 JPA/JDBC/MyBatis-Flex/R2DBC 模块中完成。

4. 删除能力语义

  • 逻辑删除使用 ILogicDelete* 系列接口
  • 恢复已删除数据由 recovery(...) 暴露
  • 物理删除使用 IPhysicsDelete* 系列接口
  • 删除前保护、删除后清理和恢复补偿规则见 delete-hook-and-logging-guide.md

查询接入步骤

1. 定义查询 Web 入口

列表查询入口是 ISearchController,接收 CommonParameters 与业务 Query 组装为 QueryParameters

按 ID 查询入口是 IFindByIdController,支持 GET /{id}(单条)和 GET /batch?idSet=...(批量)。

2. 定义查询 Service / Manager

列表查询:ISearchServiceISearchManager,返回 QueryResults

按 ID 查询:IFindByIdServiceIFindByIdManager

3. 统一参数与返回模型

  • QueryParameters 统一承载 searchKeycurrentpageSizesorterListqueryObject
  • AbstractVO 作为标准返回对象基类
  • ResponseResults<T> 作为统一响应外壳

4. 扩展查询入口

查询能力 路径常量 返回模型
回收站查询 Urls.SEARCH_RECYCLE QueryResults<V>
字典查询 Urls.SEARCH_DICTIONARY QueryResults<DictionaryValue>
树查询 Urls.SEARCH_TREE QueryResults<TN>
树字典查询 Urls.SEARCH_TREE_DICTIONARY QueryResults<DictionaryValueTreeNode>
按主对象查询 Urls.SEARCH_OF_MASTER_ID MasterQueryResults<M, V>
按主对象字典查询 Urls.SEARCH_DICTIONARY_OF_MASTER_ID QueryResults<DictionaryValue>
按主对象字典树查询 Urls.SEARCH_DICTIONARY_TREE_OF_MASTER_ID MasterQueryResults<M, DictionaryValueTreeNode>

SearchOfMasterId 是主从/关联场景:先用 IFindByIdManager 查主对象,再用 ISearchManager 查询关联列表。

动态注册约定

ineed-core-webmvc 扫描 IWebMvcApi Bean,ineed-core-webflux 扫描 IWebFluxApi Bean,把标准接口默认方法注册到路由中。

业务控制器通常只需要:

  • 实现对应 I*Controller 接口
  • 提供 getResourceKey()getResourceName()
  • 不需要为每个默认方法重复手写转发

getResourceKey()getResourceName() 优先返回模块常量中的 XxxConstant.Resource.KEY_* / XxxConstant.Resource.NAME_*getResourceName() 返回业务展示名,OpenAPI 公共接口摘要会用它将 资源 占位替换为具体业务名称。

响应式实现约束

WebFlux 实现必须避免将响应式链路退化成装配期同步执行:

  • 自定义 WebFlux Controller 方法统一返回 Mono.defer(() -> { ... }),把入口日志、上下文读取、参数准备和结果封装都放进订阅期
  • Controller 中包装 Service 返回值时优先使用 ResultBuild.success(serviceMono);不要在链外先执行日志或同步逻辑后再用 serviceMono.flatMap(ResultBuild::success) 拼接
  • Controller 参数校验通过 Mono.defer(...)ValidationExceptionSupport.validate(...) 延迟到订阅期
  • 无返回体动作型接口统一返回 Mono<ResponseResults<Void>>,使用 .then(ResultBuild.success())
  • 集合结果返回 Mono<ResponseResults<Iterable<T>>>,不生成 Mono<ResponseResults<Flux<T>>>
  • Flux 只保留在 Service / Manager 内部或真正的流式接口中
  • R2DBC manager / repository 中不使用 Mono.just(getEntityClass()) 等装配期求值写法,使用 Mono.defer(...)getEntityClassMono()

WebMvc 与 WebFlux 对齐要求

同一业务对象如果同时暴露两条线,必须保持一致:

  • URL 路径一致
  • 权限资源后缀一致
  • 参数名一致(commonqueryidSet
  • getResourceKey() / getResourceName() 语义一致
  • 返回 ResponseResults / QueryResults / MasterQueryResults 结构一致
  • 标准能力组合一致,除非需求明确排除

非业务对象级内置入口

ineed-core-webmvcineed-core-webflux 还包含健康检查、i18n 语言列表和应用模块元数据等内置 Controller。这些属于框架运行支撑,生成业务模块时不要为每个业务对象复制。

运行与验证

阻塞式主链路验证:

mvn -pl ineed-core-tests/ineed-core-test-webmvc -am \
  -Dtest=WebMvcJpaBusinessChainTest,WebMvcJdbcBusinessChainTest,WebMvcMybatisFlexBusinessChainTest,\
WebMvcJpaSearchBusinessChainTest,WebMvcJdbcSearchBusinessChainTest,WebMvcMybatisFlexSearchBusinessChainTest \
  -Dsurefire.failIfNoSpecifiedTests=false test

响应式主链路验证:

mvn -pl ineed-core-reactive-modules/ineed-core-webflux,ineed-core-tests/ineed-core-test-webflux -am test

当前不覆盖

最后更新:2026-05-15

仍有疑问?按反馈清单整理复现信息 →