V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
abc9999
V2EX  ›  问与答

一对多时 Mybatis 的分页方案

  •  
  •   abc9999 · 361 天前 · 1389 次点击
    这是一个创建于 361 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一个 blog 表,一个 attachment 表,一个 blog 对应多个 attachment.
    主表是 blog ,
    如果查询条件只过滤 blog ,那分页很简单。
    如果查询条件同时过滤 blog 和 attachment ,应该怎么优雅的分页?
    目前想到的方案是:
    sql1:
    select distinct blog.id
    from blog left join attachment
    where 查询条件
    limit 分页,
    (得到分页后的主表 blog 的 id 集合)
    sql2:
    select blog.*, attachment.*
    from blog left join attachment
    where 查询条件
    and blog.id in (sql1 查出来的 id)

    有点麻烦,想问问 v 友们有没有优雅的方案?
    7 条回复    2023-12-23 13:42:43 +08:00
    nerkeler
        1
    nerkeler  
       361 天前 via Android
    select blog2.xxxatta.xxx from (select blog.id ,... where xxx limit) blog2 left join att... 先把 blog 表查出来分页结果,当做主查询的临时查询表,再去关联 atta 表
    pannanxu
        2
    pannanxu  
       361 天前
    从设计层面来讲,blog 和 attachment 是两个模块,考虑扩展性最好不要直接写 sqljoin ,应该从应用层做处理。或者是 blog 冗余一份 attachment
    abc9999
        3
    abc9999  
    OP
       361 天前 via iPhone
    @nerkeler 如果查询条件只过滤 attachment 表,这么写会导致查 blog 全表
    abc9999
        4
    abc9999  
    OP
       361 天前
    @pannanxu 应用层处理也是个方案,在代码里面拼分页,但是实现也很繁琐,有没有更优雅的方式呢
    Dongxiaohao
        5
    Dongxiaohao  
       361 天前 via Android
    蹲,也遇到类似的场景,解决办法和 op 一样,把主表的 ID 算出来去多的那张表 in 它的 ID
    pannanxu
        6
    pannanxu  
       361 天前
    @abc9999 #4 那就让前端自己调用 attachment 接口获取 blogIds 相关的数据
    vishun
        7
    vishun  
       361 天前
    感觉这个和 n+1 问题的解决方法是一致的,第二个 sql 不要再联表了,而是只根据 blogIds 取 attachment 表中所有数据,然后其他的放到应用层处理,group by 一下组装成 blogId 和 attachmentList 的 map ,然后再遍历原有的 blogList ,将 attachementList 附加到 blog 列表中。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5264 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 07:37 · PVG 15:37 · LAX 23:37 · JFK 02:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.