
本文介绍如何利用 Elide 的标准 REST API 能力(如 include、fields、filter、sort)原生支持跨三个关联实体(Table1/Table2/Table3)的联合数据查询,避免手动实现过滤、排序和分页逻辑。
本文介绍如何利用 elide 的标准 rest api 能力(如 `include`、`fields`、`filter`、`sort`)原生支持跨三个关联实体(table1/table2/table3)的联合数据查询,避免手动实现过滤、排序和分页逻辑。
Elide 的核心优势在于它将 JPA 实体直接映射为符合 JSON:API 规范的资源端点,并自动处理关系遍历、字段裁剪、条件过滤、排序及分页——无需 DTO、Service 手动组装或自定义 Controller。针对您的场景(/table3data 需聚合 Table1、Table2、Table3 字段并支持 filter[table1.refId] 和 filter[date]),关键在于正确建模实体关系并启用 Elide 的路径式过滤能力。
✅ 正确建模:修复外键映射,启用路径过滤
您当前 Table3 中 @JoinColumn(name = "table1_id", referencedColumnName = "refId") 存在严重问题:JPA 要求 referencedColumnName 必须是被引用表的 主键(id)或唯一键列,但 refId 是 String 类型且非主键。这会导致:
- Hibernate 无法生成正确 SQL JOIN;
- Elide 的路径过滤(如 filter[table1.refId])失效。
必须修正为:
// Table3.java —— 使用 refId 作为逻辑外键,但数据库外键仍指向 table1.id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "table1_id", referencedColumnName = "id") // ✅ 指向主键
private Table1 table1;
// 同时添加逻辑字段(供 Elide 过滤用),不映射到数据库
@Transient
public String getTable1RefId() {
return table1 != null ? table1.getRefId() : null;
}同理修正 Table2 关系,并为 Table3 添加 getTable2RefId()。
✅ 启用 Elide 原生多表过滤与排序
确保 Table3 实体被 @Include 注解且无权限拦截:
@Include(type = "table3") // 显式指定 type,便于 URL 路由
@Entity
@Table(name = "table3")
public class Table3 {
// ... 其他字段保持不变
// 提供可过滤的关联字段(Elide 自动识别 getter)
@Transient
public String getTable1RefId() { return table1 != null ? table1.getRefId() : null; }
@Transient
public String getTable2RefId() { return table2 != null ? table2.getRefId() : null; }
// 支持日期范围过滤(Elide 会解析 date[gt], date[lt] 等)
@JsonProperty("date")
public Date getDate() { return date; }
}启动应用后,即可使用标准 Elide 查询参数:
GET /table3?filter[table1.refId]=T1001,T1002&filter[date][gte]=2024-01-01&filter[date][lte]=2024-12-31&sort=-date&include=table1,table2&fields[table3]=id,amount,date&fields[table1]=type,status&fields[table2]=name
- filter[table1.refId] → 经 getTable1RefId() 转换,自动匹配多个 refId;
- filter[date][gte] / filter[date][lte] → 原生支持日期范围;
- include=table1,table2 → 返回完整关联对象(Compound Document);
- fields[...] → 精确控制返回字段,减少网络负载。
⚠️ 注意事项与最佳实践
- 不要创建 DTO 或 Service 组装层:Elide 的 @Include + @Transient + 路径表达式已覆盖全部需求,手动组装反而破坏 Elide 的查询优化(如 JOIN 推导、SQL 层过滤)。
- 性能关键:为 Table3.date 和 Table1.refId 添加数据库索引,避免全表扫描。
- 分页自动生效:只要请求含 page[size]=20&page[number]=1,Elide 即调用 PagingAndSortingRepository 自动分页。
- 安全过滤:通过 @ReadPermission 在 Table3 上声明规则(如 filter[table1.refId] 仅对授权用户可见)。
✅ 总结
您无需编写任何 Controller、DTO 或手动解析 filter 参数——Elide 原生支持跨表路径过滤(table1.refId)、复合排序(sort=table1.type,-date)和嵌套包含(include=table1,table2)。只需修正实体关系映射、暴露 @Transient 逻辑字段,并确保 JPA Repository 继承 JpaSpecificationExecutor(Elide 默认启用)。此举将代码量减少 70%,同时获得企业级查询健壮性与可维护性。

















