请教有关 ORM 1+N 查询的问题

2019-04-21 11:24:25 +08:00
 ydc886

举个例子,T_A 这张表中,有 T_B.id FK,T_C.id FK,T_D.id FK. 业务上,查询想要带出 T_B.name, T_C.name, T_D.name。这个问题,我想到常见的方案是:1. 数据库下手,加冗余字段,这个方案会引入是更新时也要修改冗余字段,此外,业务上,在页面展示的数据增加额外的列也很常见,那就要再扩充冗余字段。2. 主表查询到结果后,取外键集合在各个外键表用 in id 查询,这个也是我在工程里常用的方式。3. 二级缓存,这就需要设计缓存更新了吧(这个和第二种方式类似,维护一个映射)。除了这三个还有啥思路吗?

3066 次点击
所在节点    Java
9 条回复
jamesxu
2019-04-21 12:15:37 +08:00
联表查啊
reus
2019-04-21 13:31:27 +08:00
本来用 JOIN 无比简单的事情,套了个 ORM 就各种不顺

那你还用 ORM 干嘛?
shihaoyu
2019-04-21 14:44:08 +08:00
不知道楼主的 ORM 是什么框架的下的,Django 的 ORM 有一个 select_related 方法解决一对多的 1+N 查询,prefetch_related 方法解决多对多的 1+N 问题。实际上翻译成 sql 语句后也是使用 join,我想 Java 里面的框架应该也有类似的解决方案。希望能帮到楼主。
ydc886
2019-04-21 16:08:12 +08:00
@shihaoyu 嗯,各类方法的实质上也是 join,或者会话期间懒加载拿数据。这也是流行的 ORM 框架的基本功能。
ydc886
2019-04-21 16:32:28 +08:00
@reus 哈哈,这类操作就是很基础的东西,怎么写都行。这类 name 或者 sex 之类没什么业务逻辑的字段,取出来也就塞在 VO 中一个新的域,某个领域对象是业务核心对象,那么其查询时关联一些数据要挺多,这出现的是 join 多了,sql 变长了。就在找个折衷点。标题也不是很恰当。JPA 的 EntityGraph,Spring JPA 的 projections,这些我理解也是对这种场景的抽象。
ydc886
2019-04-21 16:39:38 +08:00
再者,这东西稍微再扩展一下。几张表不在一个同一个 schema,又怎么玩。这些东西日常刷刷写,也想提炼一下,但是没想到如何描述,在搜索引擎就困难找到相关的 blog,就希望作为一个问题,看大家给一些 keyword,让我按图索骥。
TommyLemon
2019-04-21 17:50:44 +08:00
APIJSON,自动化接口和文档 ORM 库,
支持 LEFT JOIN, RIGHT JOIN, INNER JOIN, OUTTER JOIN, FULL JOIN, APP JOIN。
前端只要传一个 join 键值对,例如 "join":"</User/id@" ,
后端就自动生成了 JOIN 的 SQL 语句,如果用的是 APP JOIN
例如 "join":"@/User/id@" ,则会自动实现第 2 中方式,
从主表去除所有关联字段的值 refKey,组成数组 refKeys,
然后对副表生成 id IN($refKeys) 自动优化性能。
注意,后端没有写任何一行代码,以上过程就自动完成了!



🏆码云最有价值开源项目
🚀后端接口和文档自动化,前端(客户端) 定制返回 JSON 的数据和结构!
GitHub 右上角点 Star 支持下吧 ^_^
https://github.com/TommyLemon/APIJSON
icaca
2019-04-21 19:39:36 +08:00
写个视图吧 用 orm 框架查询视图 还能解决排序的问题
TommyLemon
2019-04-22 12:07:17 +08:00
@icaca 视图是要开发和维护成本的,看 #7 回答,很好的方案

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/557195

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX