ORM
ORM,全称 Object-Relational Mapping(对象关系映射),是编程语言对象与关系型数据库之间的操作层。
在 Geelato Framework 中,该能力并非单点 API,而是一组围绕"元数据 + 查询协议 + Java DSL + 扩展机制"组织起来的体系:
- 注解层:描述 Java 对象如何映射到表、列和元数据标题
- 协议层:通过
MetaController + MQL承载前端和平台通用数据访问 - Java API 层:通过
MetaFactory + Fluent DSL承载后端服务代码中的 CRUD 与轻量高级查询 - 扩展层:通过事件、动态数据源、查询过滤/字段填充 SPI 等机制承载平台级规则与扩展能力
ORM 能力现状
Geelato ORM 的能力特点:
- 不是 JPA/Hibernate 那种"实体状态管理优先"的重量级 ORM。
- 也不是只做简单表映射的轻量工具类集合。
- 核心是"以元数据为中心"的统一数据访问体系。
- 查询与写入能力拆分为不同入口,分别服务不同层级。
可将这套能力理解为分层协作:
@Entity / @Col / @Title / @Transient解决"对象与表结构如何声明"。MQL解决"前端、平台协议侧如何用 JSON 描述查询与写入"。Fluent DSL解决"后端 Java 服务如何以链式 API 发起查询、保存、更新、删除"。- 事件、动态数据源、SPI 扩展解决"主链路之外的平台规则如何注入"。
Geelato ORM 并非仅有 geelato-orm 一个模块,而是多模块协作:
geelato-orm:后端 Java 侧的 ORM 主入口与执行链路。geelato-core、geelato-lang:元数据与部分基础契约。MQL:平台协议侧的数据访问表达。geelato-web-platform:默认平台规则的落地实现。
ORM 的目的
这套 ORM 体系主要为了解决这些问题:
- 让 Java 对象、数据库表字段、元数据标题保持统一声明
- 让平台协议侧和后端 Java 侧都可以复用同一套元数据模型
- 避免在服务层频繁手写 MQL JSON、DAO 样板代码或散落的 SQL 拼装
- 把动态数据源、视图参数、上下文取值、默认字段填充、权限过滤等框架能力统一收口
- 把平台默认规则从底层 CRUD 里解耦出来,改为通过事件或 SPI 注入
四类入口如何分工
1. ORM 注解
注解层回答的是“实体是什么”。
它主要负责:
- 一个 Java 类对应哪个实体名、哪张表
- 一个 Java 字段对应哪一列、有哪些列级约束
- 哪些字段只是运行时属性,不参与持久化
- 哪些实体和字段需要补充标题、描述等元数据信息
典型使用方式:
@Entity(name = "User", table = "platform_user")
@Title(title = "用户")
public class User extends BaseEntity {
@Title(title = "用户名")
private String name;
@Col(name = "login_name")
@Title(title = "登录名")
private String loginName;
@Transient
private List<Role> roles;
}
对应文档见 ORM 注解说明。
2. MQL
MQL 回答的是“平台协议侧如何访问数据”。
它主要面向:
- 前端页面
- 平台通用数据接口
- 低代码配置或 JSON 协议场景
典型能力包括:
@fs字段选择@p分页@order排序@group分组@b复杂括号逻辑@pf视图模板参数ref(...)关联字段$ctx.* / $fn.* / $parent.*内置变量
典型使用方式:
{
"platform_user": {
"@fs": "id,name,loginName",
"@p": "1,10",
"@order": "updateAt|-",
"delStatus": 0
}
}
MQL 与 ORM 强相关,但它的定位不是 Java 侧 DSL,而是平台通用 JSON 协议。
3. Fluent DSL
Fluent DSL 回答的是“后端 Java 服务如何访问数据”。
它主要面向:
- 服务端业务代码
- Java 里的标准 CRUD
- 轻量 join、分页、聚合、过程调用
- 需要复用动态数据源、视图参数、值引用等框架能力的场景
典型能力包括:
MetaFactory.query(...)MetaFactory.insert(...)MetaFactory.update(...)MetaFactory.delete(...)MetaFactory.procedure(...)MetaFactory.sql(...)selectRef(...)leftJoin/innerJoin/rightJoinuseDataSource(...)viewParams(...)ValueRefs.ctx/fn/parent
典型使用方式:
List<Map<String, Object>> users = MetaFactory.query("User")
.select(new String[]{"id", "name", "mobilePhone"})
.where(Filter.eq("delStatus", 0))
.order(Order.desc("updateAt"))
.page(1, 10)
.page();
对应文档见 Fluent DSL 指引。
4. 高级特性与扩展机制
高级特性回答的是“标准 CRUD 之外的平台能力如何接入”。
当前主要包括四类:
- ORM 事件:在保存和删除前后挂接监听器
- 动态数据源:按运行时 key 切换数据源
- 查询过滤 SPI:把租户、权限等平台级过滤规则注入查询链路
- 字段填充 SPI:在保存链路自动补齐审计字段、租户字段等默认值
ORM 事件怎么用
适合做:
- 保存前校验
- 保存后审计、缓存刷新、镜像同步
- 删除前约束拦截
- 删除后旁路清理
对应文档见 ORM 事件特性。
动态数据源怎么用
适合做:
- 同一套服务代码访问不同数据源
- 在 Fluent DSL 或 SQL 直通执行时显式切换数据源
- 在宿主工程里替换动态数据源定义来源
对应文档见 ORM / 数据源扩展 和 动态数据源。
注入扩展怎么用
适合做:
- 自动注入租户过滤、权限过滤、组织隔离条件
- 自动填充创建人、更新时间、租户编码等默认字段
- 在宿主项目中替换平台默认规则,而不修改底层模块
当前推荐扩展入口:
FluentQueryFilterInjectorMqlQueryFilterInjectorFluentSaveFieldValueFillerMqlSaveFieldValueFillerEntitySaveFieldValueFiller
对应文档见 查询过滤与字段填充 SPI 扩展。
推荐使用边界
推荐优先使用 Geelato ORM 体系的场景:
- 后端服务中需要按实体名或实体类做标准 CRUD
- 页面或平台通用接口需要用 JSON 协议描述查询和保存
- 需要少量关联字段、分页、排序、轻量聚合或轻量存储过程调用
- 需要复用动态数据源、视图参数、默认字段填充、上下文取值等框架能力
不建议强行使用这套 ORM 体系的场景:
- 超复杂跨组过滤、递归 CTE、窗口函数等 SQL-first 查询
- 多结果集存储过程或高度依赖复杂
resultMap的场景 - 团队已经明确持有完整 SQL,且更适合直接维护 SQL 文本的场景
与其他数据访问方式的关系
MetaFactory + Fluent DSL:优先用于后端 Java 服务中的标准元数据 CRUDMetaController + MQL:优先用于平台通用数据接口和前端协议侧MetaFactory.sql(...):用于业务方已经持有完整 SQL、只想复用执行链路的场景- MyBatis / 原生 SQL:保留给超复杂查询、复杂结果映射和数据库特性较强的场景
最小接入(独立 Spring Boot)
这部分给出最短接入路径,让一个普通 Spring Boot 工程可以直接使用 MetaFactory 完成 CRUD。
最小依赖:
<dependency>
<groupId>cn.geelato</groupId>
<artifactId>geelato-orm</artifactId>
</dependency>
最小 Bean:
@Configuration
public class OrmDaoConfiguration {
@Bean
public Dao primaryDao(JdbcTemplate jdbcTemplate) {
return new Dao(jdbcTemplate);
}
}
元数据准备:
- 默认会扫描 Spring Boot 启动类所在包及子包内的
@Entity并注册到元数据管理器
自动装配包含什么
geelato-orm 在 Spring Boot 环境中当前自动装配这些能力:
MetaExecutionStrategy:根据配置选择基于Dao或JdbcTemplate的执行策略MetaCommandExecutor:承接 Fluent DSL 的执行SaveDefaultValueFiller:兼容层默认字段填充 BeanBeansUtils:用于在执行路径中获取 Spring Bean- 实体元数据自动注册:扫描
@Entity并注册到元数据管理器 - 默认数据源初始化:推导并注册默认数据源 key
推荐阅读顺序
- 先看 ORM 注解说明,理解对象与表结构如何映射
- 再看 MQL 总览,理解平台协议侧如何访问数据
- 再看 Fluent DSL 指引,理解后端 Java 侧如何访问数据
- 再看 ORM 事件特性 与 ORM / 数据源扩展,理解高级扩展机制
- 最后结合 查询过滤与字段填充 SPI 扩展 和 核心模块说明 理解整体架构