前言MySQL一对多的数据分页是一个很常见的需求,比如我们要查询商品和商品图片信息。但是很多人会在这里遇到分页错误,得到不正确的结果。今天就来分析解决这个问题。2.问题分析我们先建立一个简单的商品表和对应的商品图片关系表,它们之间是一对多的关系:然后写了一些商品和这些商品对应的图片,通过左边查询下面加入可以看出它们之间存在明显的一对多关系:SELECTP.PRODUCT_ID,P.PROD_NAME,PI.IMAGE_URLFROMPRODUCT_INFOPLEFTJOINPRODUCT_IMAGEPIONP.PRODUCT_ID=PI.PRODUCT_ID按照传统思维,我们的分页语句会这样写:SELECTP.PRODUCT_ID,P.PROD_NAME,PI.IMAGE_URLFROMPRODUCT_INFOPLEFTJOINPRODUCT_IMAGEPIONP.PRODUCT_ID=PI.PRODUCT_IDLIMIT#{current},#{size}当我按预期传入(0,2)得到前两个产品的数据时,结果不是我预期的:2020-06-2123:35:54.515DEBUG10980---[main]c.f.m.mappers.ProductInfoMapper.page:==>准备中: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:>Paramepage:(长),2(Long)2020-06-2123:35:54.565DEBUG10980---[main]c.f.m.mappers.ProductInfoMapper.page:<==Total:2page=[ProductDTO{productId=1,prodName='cup',imageUrls=[http://asset.felord.cn/cup1.png,http://asset.felord.cn/cup2.png]}]我期望的两个数据是cup和notebook,结果只有一个当一个-to-manymapping,结果集会按照multi-side输出(预计4条数据,实际会有7条),而前两条只会显示cup的数据(如下图)上图),而合并后,只会有一个结果,所以分页不会匹配。那么如何才能达到我们期望的分页效果呢?3、正确的做法正确的思路是先对主表进行分页,再关联副表进行查询。抛开框架,我们的SQL应该先分页查询product表,再查询左联image表:SELECTP.PRODUCT_ID,P.PRODUCT_NAME,PI.IMAGE_URLFROM(SELECTPRODUCT_ID,PROD_NAMEFROMPRODUCT_INFOLIMIT#{current},#{size})PLEFTJOINPRODUCT_IMAGEPIONP写成.PRODUCT_ID=PI.PRODUCT_ID的好处是比较通用。但是MyBatis提供了一种比较优雅的方式,思路还是一开始说的思路。只是我们需要修改上面的MybatisXML配置:prodName"column="prod_name"/>SELECTPRODUCT_ID,PROD_NAMEFROMPRODUCT_INFOLIMIT#{current},#{size}SELECTIMAGE_URLFROMPRODUCT_IMAGEWHEREPRODUCT_ID=#{productId}4.综上所述,分页在大多数情况下很容易,但还是有一些小型的一对多陷阱。一旦我们了解了机制,解决起来就不难了。当然,如果大家有更好的解决方案,可以留言讨论,集思广益。多关注:码农小胖哥,获取更多开发技巧。