您好,登錄后才能下訂單哦!
本篇文章為大家展示了一對多分頁的SQL應該怎么寫,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
前言
MySQL一對多的數據分頁是非常常見的需求,比如我們要查詢商品和商品的圖片信息。但是很多人會在這里遇到分頁的誤區,得到不正確的結果。今天就來分析并解決這個問題。
2. 問題分析
我們先創建一個簡單商品表和對應的商品圖片關系表,它們之間是一對多的關系:
然后我分別寫入了一些商品和這些商品對應的圖片,通過下面的左連接查詢可以看出它們之間具有明顯的一對多關系:
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
按照傳統的思維我們的分頁語句會這么寫:
<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: 2 page = [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_URL FROM (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>
大部分情況下分頁是很容易的,但是一對多還是有一些小小的陷阱的。一旦我們了解了其中的機制,也并不難解決。
上述內容就是一對多分頁的SQL應該怎么寫,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。