MySQL一对多的数据分页是非常常见的需求

分类 : .NET技术

1. 前言

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

2. 问题分析

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

一对多关系

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

SELECT P.PRODUCT_ID, P.PROD_NAME, PI.IMAGE_URLFROM PRODUCT_INFO P         LEFT JOIN PRODUCT_IMAGE PI                   ON P.PRODUCT_ID = PI.PRODUCT_ID

所有的一对多结果

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

    <resultMap id="ProductDTO" type="cn.felord.mybatis.entity.ProductDTO">        <id property="productId" column="product_id"/>        <result property="prodName" column="prod_name"/>        <collection property="imageUrls"  ofType="string">            <result column="image_url"/>        </collection>    </resultMap>    <select id="page" resultMap="ProductDTO">        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}    </select>               

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

2020-06-21 23:35:54.515 DEBUG 10980 --- [main] c.f.m.mappers.ProductInfoMapper.page     : ==>  Preparing: 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 ?,? 2020-06-21 23:35:54.541 DEBUG 10980 --- [main] c.f.m.mappers.ProductInfoMapper.page     : ==> Parameters: 0(Long), 2(Long)2020-06-21 23:35:54.565 DEBUG 10980 --- [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应该先对产品表进行分页查询然后再左关联图片表进行查询:

SELECT P.PRODUCT_ID, P.PROD_NAME, PI.IMAGE_URLFROM (SELECT PRODUCT_ID, PROD_NAME      FROM PRODUCT_INFO      LIMIT #{current},#{size}) P         LEFT JOIN PRODUCT_IMAGE PI                   ON P.PRODUCT_ID = PI.PRODUCT_ID

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

<resultMap id="ProductDTO" type="cn.felord.mybatis.entity.ProductDTO">    <id property="productId" column="product_id"/>    <result property="prodName" column="prod_name"/>     <!-- 利用 collection 标签提供的 select 特性 和 column   -->    <collection property="imageUrls" ofType="string" select="selectImagesByProductId" column="product_id"/></resultMap><!-- 先查询主表的分页数据    --><select id="page" resultMap="ProductDTO">    SELECT PRODUCT_ID, PROD_NAME    FROM PRODUCT_INFO    LIMIT #{current},#{size}</select><!--根据productId 查询对应的图片--><select id="selectImagesByProductId" resultType="string">    SELECT IMAGE_URL    FROM PRODUCT_IMAGE    WHERE PRODUCT_ID = #{productId}</select>

4. 总结

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

https://www.cnblogs.com/felordcn/p/13180585.html



相关文章

HTML 对象:Option value 属性



分类: .NET技术    访问() .NET技术    Web前端    JAVA开发    HTML基础    数据库    电脑知识    CSS基础
CSS教程-web前端教程-免费教程
HTML教程-web前端教程-免费教程

分类

.NET技术 Web前端 JAVA开发 HTML基础 数据库 电脑知识 CSS基础

随机阅读

HTML是什么东西?能不能删?
html语言是什么?html详细介绍!
css 宽度(CSS width)
html <a>标签锚点跳转的简单应用
body的onload事件怎么同时加载两个函数
oracle sql like多个条件函数
oracle数据库模糊查询匹配多个字符串
oracle字段like多个条件
Java:String和Date、Timestamp之间的转换
Spring Boot 教程 - MyBatis-Plus
如何用u盘重装系统?用U大侠U盘启动制作盘安装Win7系统教程
方正综艺简体下载大全,什么方正综艺简体字体下载
C#遍历指定文件夹中的所有文件
Mysql和Redis数据同步策略
java String类型与Date日期类型互相转换

最新

零基础学习C语言,怎么入门?
C语言使用什么软件?
c语言用什么软件编写(新手c语言基础知识入门)
Oracle如何实现like多个值的查询
Oracle如何实现like多个值的查询 - 数据库
oracle 多个like条件查询
Oracle中关键字like的使用总结
oracle 中模糊查询对like的代替insrt()函数
oracle数据库模糊查询匹配多个字符串
Oracle如何实现like多个值的查询 - Oracle - 服务器

推荐阅读

vscode----vue中HTML代码tab键自动补全
html如何实现鼠标悬停显示文字,鼠标移走文字消失。
c语言中break语句的作用
C#语言之“string格式的日期时间字符串转为DateTime类型”
undefined是什么意思啊
DIV CSS字体(font-family)实现字体样式设置
AirPods怎么删除配对过的设备 airpods可以和电脑连接的
js 中日期 转换成时间戳 例如2013-08-30 转换为时间戳
risk-taking中文是什么意思
replace和replaceAll是JAVA中常用的交换字符的办法

Copyright © 2017 CSS5.NET教程.CSS5 内容仅用于学习和测试参考。 css5.net All Rights Reserved 蜀ICP备15003849号-16