1. 程式人生 > >SpringBoot Mybatis解決使用PageHelper一對多分頁問題

SpringBoot Mybatis解決使用PageHelper一對多分頁問題

  一般來說使用 PageHelper 能解決絕大多數的分頁問題,相關使用可在部落格園上搜索,能找到很多資料。

  之前我在做SpringBoot 專案時遇到這樣一個問題,就是當一對多聯合查詢時需要分頁的情況下,使用 PageHelper 做不到對一來進行分頁,而是對查詢結果做的分頁。

  後來經過查詢相關資料,找到了一個使用 PageHelper 根據一來進行分頁的一對多聯合查詢,方法就是巢狀子查詢,這樣的話分頁結果就是需要的效果。

  特此將相關程式碼記錄一下,備忘。

  這裡使用常見的例子 商品與商品資訊 ,在MySql資料庫建立兩張相對應的表,

CREATE TABLE `item` (
  `item_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '商品編號',
  `img_url` varchar(500) NOT NULL DEFAULT '' COMMENT '圖片地址',
  `title` varchar(1000) NOT NULL COMMENT '標題',
  `price` varchar(500) NOT NULL COMMENT '價格',
  `item_type` varchar(30) NOT NULL COMMENT '類別',
  `quantity` bigint(20) NOT NULL COMMENT '數量',
  PRIMARY KEY (`item_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='商品';
CREATE TABLE `item_sku` (
  `sku_id` bigint(20) NOT NULL AUTO_INCREMENT  COMMENT '規格ID',
  `item_id` varchar(30) NOT NULL COMMENT '商品ID',
  `sku_price` varchar(100) NOT NULL DEFAULT '' COMMENT 'SKU價格',
  `sku_unique_code` varchar(100) NOT NULL COMMENT '規格唯一標識',
  `quantity` bigint(20) NOT NULL COMMENT '數量',
  PRIMARY KEY (`sku_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='商品SKU';

  在專案中新建相關的model類和mapper介面與xml檔案,在xml檔案中新增 resultMap 

下方的property欄位對應關係說明 <!--property欄位對應的itemSkus必須在結果集中List的欄位名 如:private List<ItemSku> itemSkus;--> 

    <resultMap id="item" type="com.demo.dal.entity.pojo.Item">
        <result column="item_id" jdbcType="VARCHAR" property="itemId"/>
        <result column="img_url" jdbcType="VARCHAR" property="imgUrl"/>
        <result column="title" jdbcType="VARCHAR" property="title"/>
        <result column="price" jdbcType="VARCHAR" property="price"/>
        <result column="item_type" jdbcType="VARCHAR" property="itemType"/>
        <result column="quantity" jdbcType="BIGINT" property="quantity"/>

        <collection property="itemSkus" ofType="com.demo.dal.entity.pojo.ItemSku"
                    javaType="java.util.List" select="getSkuByItemId"
                    column="{itemId=item_Id}"><!--{itemId=item_Id,quantity=quantity} 要查詢的列 必須在父查詢的select欄位中-->   <!--property欄位對應的itemSkus必須在結果集中List的欄位名 如:private List<ItemSku> itemSkus;-->
            <result column="sku_id" jdbcType="VARCHAR" property="skuId"/>
            <result column="sku_price" jdbcType="VARCHAR" property="skuPrice"/>
            <result column="sku_unique_code" jdbcType="VARCHAR" property="skuUniqueCode"/>
            <result column="quantity" jdbcType="BIGINT" property="quantity"/>
        </collection>
    </resultMap>

  主查詢語句 selectItemAndSku 

<select id="selectItemAndSku" resultMap="item" parameterType="map">
        SELECT
        s1.item_id,
        s1.title,
        s1.img_url,
        s1.item_type,
        s1.price,
        s1.quantity,
        FROM
        item s1
        <where>
            <if test="title != null and title != ''">
                AND s1.title LIKE '%${title}%'
            </if>
            <if test="itemId != null and itemId != ''">
                AND s1.item_id = '${itemId}'
            </if>
        </where>
        order by item_id desc
    </select>

  子巢狀查詢語句 getSkuByItemId 

<select id="getSkuByItemId" parameterType="map"
            resultType="map">
select s2.sku_id,
        s2.sku_price,
        s2.sku_unique_code,
        s2.quantity,
from item_sku s2
where
s2.item_id = #{itemId}
ORDER BY s2.sku_id
</select>

  當這些都完成後,在mapper介面檔案中新新增這樣一個方法:  List<Item> selectItemAndSku(Map<String, Object> map); 

  然後在service實現類中就可以注入mapper介面類,然後使用分頁外掛來進行分頁了。

示例程式碼:

  PageInfo<Item> pageInfo =
          PageHelper.startPage(page, pageSize)
              .doSelectPageInfo(
                  () ->
                      itemDao.selectItemAndSku(map);//JDK 8.0以上的語法
                     
  //List<Item> list = PageHelper.startPage(page, pageSize);
  //itemDao.selectItemAndSku(map);
  //PageInfo<Item> pageInfo = new PageInfo<>(list); //通用寫法
pageInfo 就是分頁出來的結果。通過controller返回出去看看結果