一对多分页的SQL应该怎么写
本篇文章为大家展示了一对多分页的SQL应该怎么写,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
前言
MySQL一对多的数据分页是非常常见的需求,比如我们要查询商品和商品的图片信息。但是很多人会在这里遇到分页的误区,得到不正确的结果。今天就来分析并解决这个问题。
2. 问题分析
我们先创建一个简单商品表和对应的商品图片关系表,它们之间是一对多的关系:
然后我分别写入了一些商品和这些商品对应的图片,通过下面的左连接查询可以看出它们之间具有明显的一对多关系:
SELECTP.PRODUCT_ID,P.PROD_NAME,PI.IMAGE_URLFROMPRODUCT_INFOPLEFTJOINPRODUCT_IMAGEPIONP.PRODUCT_ID=PI.PRODUCT_ID
按照传统的思维我们的分页语句会这么写:
<resultMapid="ProductDTO"type="cn.felord.mybatis.entity.ProductDTO"><idproperty="productId"column="product_id"/><resultproperty="prodName"column="prod_name"/><collectionproperty="imageUrls"ofType="string"><resultcolumn="image_url"/></collection></resultMap><selectid="page"resultMap="ProductDTO">SELECTP.PRODUCT_ID,P.PROD_NAME,PI.IMAGE_URLFROMPRODUCT_INFOPLEFTJOINPRODUCT_IMAGEPIONP.PRODUCT_ID=PI.PRODUCT_IDLIMIT#{current},#{size}</select>
当我按照预想传入了(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:2page=[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_URLFROM(SELECTPRODUCT_ID,PROD_NAMEFROMPRODUCT_INFOLIMIT#{current},#{size})PLEFTJOINPRODUCT_IMAGEPIONP.PRODUCT_ID=PI.PRODUCT_ID
这种写法的好处就是通用性强一些。但是MyBatis提供了一个相对优雅的路子,思路依然是开头所说的思路。只不过我们需要改造上面的Mybatis XML配置:
<resultMapid="ProductDTO"type="cn.felord.mybatis.entity.ProductDTO"><idproperty="productId"column="product_id"/><resultproperty="prodName"column="prod_name"/><!--利用collection标签提供的select特性和column--><collectionproperty="imageUrls"ofType="string"select="selectImagesByProductId"column="product_id"/></resultMap><!--先查询主表的分页数据--><selectid="page"resultMap="ProductDTO">SELECTPRODUCT_ID,PROD_NAMEFROMPRODUCT_INFOLIMIT#{current},#{size}</select><!--根据productId查询对应的图片--><selectid="selectImagesByProductId"resultType="string">SELECTIMAGE_URLFROMPRODUCT_IMAGEWHEREPRODUCT_ID=#{productId}</select>
大部分情况下分页是很容易的,但是一对多还是有一些小小的陷阱的。一旦我们了解了其中的机制,也并不难解决。
上述内容就是一对多分页的SQL应该怎么写,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。