一篇短文来教你,一对多分页的SQL到底应该怎么写?看完必会

1. 前言

MySQL一对多的数据分页是非常常见的需求,比如我们要查询商品和商品的图片信息。但是很多人会在这里遇到分页的误区,得到不正确的结果。今天就来分析并解决这个问题。

2. 问题分析

我们先创建一个简单商品表和对应的商品图片关系表,它们之间是一对多的关系:

然后我分别写入了一些商品和这些商品对应的图片,通过下面的左连接查询可以看出它们之间具有明显的一对多关系:

SELECTP.PRODUCT_ID, P.PROD_NAME, PI.IMAGE_URL

FROM PRODUCT_INFO P

LEFTJOINPRODUCT_IMAGEPI

ONP.PRODUCT_ID = PI.PRODUCT_ID

按照传统的思维我们的分页语句会这么写:

SELECT P.PRODUCT_ID, P.PROD_NAME,PI.IMAGE_URL

FROM PRODUCT_INFO P

LEFT JOIN PRODUCT_IMAGE PI

ON P.PRODUCT_ID = PI.PRODUCT_ID

LIMIT #{current},#{size}

当我按照预想传入了(0,2)想拿到前两个产品的数据,结果并不是我期望的:

2020-06-2123:35:54.515DEBUG10980---[main]c.f.m.mappers.ProductInfoMapper.page    :==>Preparing:SELECTP.PRODUCT_ID,P.PROD_NAME,PI.IMAGE_URLFROMPRODUCT_INFOPLEFTJOINPRODUCT_IMAGEPIONP.PRODUCT_ID=PI.PRODUCT_IDlimit?,?

2020-06-2123:35:54.541DEBUG10980---[main]c.f.m.mappers.ProductInfoMapper.page    :==>Parameters:0(Long),2(Long)

2020-06-2123:35:54.565DEBUG10980---[main]c.f.m.mappers.ProductInfoMapper.page    :<==Total:2

page=[ProductDTO{productId=1,prodName='杯子',imageUrls=[http://asset.felord.cn/cup1.png,http://asset.felord.cn/cup2.png]}]

我期望的两条数据是杯子和笔记本,但是结果却只有一条。原来当一对多映射时结果集会按照多的一侧进行输出(期望4条数据,实际上会有7条),而前两条展示的只会是杯子的数据(如上图),合并后就只有一条结果了,这样分页就对不上了。那么如何才能达到我们期望的分页效果呢?

3. 正确的方式

正确的思路是应该先对主表进行分页,再关联从表进行查询。

抛开框架,我们的SQL应该先对产品表进行分页查询然后再做关联图片表进行查询:

SELECTP.PRODUCT_ID, P.PROD_NAME, PI.IMAGE_URL

FROM (SELECTPRODUCT_ID, PROD_NAME

FROMPRODUCT_INFO

LIMIT#{current},#{size}) P

        LEFT JOIN PRODUCT_IMAGE PI

                  ON P.PRODUCT_ID = PI.PRODUCT_ID

这种写法的好处就是通用性强一些。但是MyBatis提供了一个相对优雅的路子,思路依然是开头所说的思路。只不过我们需要改造上面的Mybatis XML配置:

<!-- 利用 collection 标签提供的 select 特性 和 column  -->

<!-- 先查询主表的分页数据    -->

SELECT PRODUCT_ID, PROD_NAME

FROM PRODUCT_INFO

LIMIT #{current},#{size}

<!--根据productId 查询对应的图片-->

SELECT IMAGE_URL

FROM PRODUCT_IMAGE

WHERE PRODUCT_ID = #{productId}

4. 总结

大部分情况下分页是很容易的,但是一对多还是有一些小小的陷阱的。一旦我们了解了其中的机制,也并不难解决。当然如果你有更好的解决方案可以留言讨论,集思广益。多多关注小编,获取更多开发技巧。

为了给在工作和技术上遇到瓶颈的同学找到发展方向,今天特意给大家带来一位大神:

马士兵老师

清华大学毕业,历任程序员、Team Leader、Project Manager、CTO等职位,有过十几个大型项目的开发经验。看到特别复杂的技术就来气,不用简单的语言把它讲出来就不爽!

马士兵老师,推动Java生根中国,推动大数据生根中国,推动AI生根中国,视频课程下载次数累计数万次。

本月25-26号两节课!马老师来给你讲解横扫一些关于多线程的问题,吊打所有敢于提问高并发问题的面试官!

免费!免费! 免费哈!重要的事情说三遍

两天授课内容

第一天内容(预习资料找我提前领取)

第二天内容:

马老师的讲课质量怎么样?(话不多说看图)

文章到这就结束了图就截取这两张吧 ,就不一一展示了,想了解更多和想跟着马老师学习这节课内容的同学们关注小编,转发收藏文章,添加v:bjmsb07  既可以免费学习并提前领取预习资料。抓紧时间!错过来就没有了哈!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350