Java architecture train - many of nested query paging Bug Solutions

Article Directory

Introduced

Here Insert Picture Description
When carrying goods orders paging query, we Mapper is written like this:

    <select id="queryMyOrders" resultMap="myOrdersVO" parameterType="Map">
        SELECT
        od.id as orderId,
        od.created_time as createdTime,
        od.pay_method as payMethod,
        od.real_pay_amount as realPayAmount,
        od.post_amount as postAmount,
        os.order_status as orderStatus,
        oi.item_id as itemId,
        oi.item_name as itemName,
        oi.item_img as itemImg,
        oi.item_spec_name as itemSpecName,
        oi.buy_counts as buyCounts,
        oi.price as price
        FROM
        orders od
        LEFT JOIN
        order_status os
        on od.id = os.order_id
        LEFT JOIN
        order_items oi
        ON od.id = oi.order_id
        WHERE
        od.user_id = #{paramsMap.userId}
        AND
        od.is_delete = 0
        <if test="paramsMap.orderStatus != null">
            and os.order_status = #{paramsMap.orderStatus}
        </if>
        ORDER BY
        od.updated_time ASC
    </select>
    
  <resultMap id="myOrdersVO" type="com.imooc.pojo.vo.MyOrdersVO">
    <id column="orderId" property="orderId"/>
    <result column="createdTime" property="createdTime"/>
    <result column="payMethod" property="payMethod"/>
    <result column="realPayAmount" property="realPayAmount"/>
      <result column="postAmount" property="postAmount"/>
      <result column="orderStatus" property="orderStatus"/>
      <result column="isComment" property="isComment"/>

    <collection property="subOrderItemList"
                ofType="com.imooc.pojo.vo.MySubOrderItemVO">
      <result column="itemId" property="itemId"/>
      <result column="itemName" property="itemName"/>
      <result column="itemImg" property="itemImg"/>
        <result column="itemSpecId" property="itemSpecId"/>
        <result column="itemSpecName" property="itemSpecName"/>
        <result column="buyCounts" property="buyCounts"/>
        <result column="price" property="price"/>
    </collection>
  </resultMap>

Above Mapper long (three were linked table), we only need to focus on:
the <resultMap>emergence in <collection>other words MyOrdersVOproperties of the object which contains a List<MySubOrderItemVO>.

Of course, we use the paging tool is PageHelper:

        <!--pagehelper -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.12</version>
        </dependency>

In the back-end code, this is:

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedGridResult queryMyOrders(String userId,
                                         Integer orderStatus,
                                         Integer page,
                                         Integer pageSize) {

        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        if (orderStatus != null) {
            map.put("orderStatus", orderStatus);
        }
        PageHelper.startPage(page, pageSize);
        List<MyOrdersVO> list = ordersMapperCustom.queryMyOrders(map);
        return setterPagedGrid(list, page);
    }
    
    public PagedGridResult setterPagedGrid(List<?> list, Integer page) {
        PageInfo<?> pageList = new PageInfo<>(list);
        PagedGridResult grid = new PagedGridResult();
        grid.setPage(page);
        grid.setRows(list);
        grid.setTotal(pageList.getPages());
        grid.setRecords(pageList.getTotal());
        return grid;
    }

Paging is standard, but the combination of codes described above, will produce a BUG:

  • The contents of the front page number is not accurate. In other words, it was supposed to be MyOrdersVOthe number for the pageSize, but now the MyOrdersVOobject MySubOrderItemVOnumber of objects chapter in pageSize.

The reason for this situation is that we use nested queries many. In PageHelper.startPage on the Github , the plug-in authors also emphasized:

1. Please do not configure more than one PageHelper
When using Spring, you can config PageHelper by mybatis-config.xml or Spring<bean>. Select one of them, do not configure PageHelper in two ways at the same time.

2. PageHelper does not support paging with for update statement
3. PageHelper does not support Nested Results Mapping
Since the nested result mode causes the resultSet to be folded, the total number of results for the paged query will decrease after folding. So It cannot guarantee the number of paged results correctly.

That is because the results of a nested approach will lead to the result set is collapsed, so the query results page after folding the total number will be reduced, it can not guarantee the correct number of paged results.

solution


  1. Option One: a two-step inquiry

The first step: query MyOrdersVOcontent, but do not inquire about their child order MySubOrderItemVOcontent being displayed in the front null.
Step Two: When users browse to the article order when we come to query child order.

The disadvantage of this method is to increase the query request.


  1. Method two: using <collection>the selectattribute

The method and a method similar, in fact, is divided in two steps, the first step is not to query only query orders the child order, which will select three tables instead link the two tables link:

  <select id="queryMyOrders" resultMap="myOrdersVO" parameterType="Map">
    SELECT
        od.id as orderId,
        od.created_time as createdTime,
        od.pay_method as payMethod,
        od.real_pay_amount as realPayAmount,
        od.post_amount as postAmount,
        os.order_status as orderStatus,
        od.is_comment as isComment
    FROM
        orders od
    LEFT JOIN
        order_status os
    on od.id = os.order_id
    WHERE
        od.user_id = #{paramsMap.userId}
    AND
        od.is_delete = 0
        <if test="paramsMap.orderStatus != null">
          and os.order_status = #{paramsMap.orderStatus}
        </if>
    ORDER BY
        od.updated_time ASC
  </select>

After modification, will <resultMap>read:

  <resultMap id="myOrdersVO" type="com.imooc.pojo.vo.MyOrdersVO">
    <id column="orderId" property="orderId"/>
    <result column="createdTime" property="createdTime"/>
    <result column="payMethod" property="payMethod"/>
    <result column="realPayAmount" property="realPayAmount"/>
      <result column="postAmount" property="postAmount"/>
      <result column="orderStatus" property="orderStatus"/>
      <result column="isComment" property="isComment"/>

    <collection property="subOrderItemList"
                select="getSubItems"
                column="orderId"
                ofType="com.imooc.pojo.vo.MySubOrderItemVO">
      <result column="itemId" property="itemId"/>
      <result column="itemName" property="itemName"/>
      <result column="itemImg" property="itemImg"/>
        <result column="itemSpecId" property="itemSpecId"/>
        <result column="itemSpecName" property="itemSpecName"/>
        <result column="buyCounts" property="buyCounts"/>
        <result column="price" property="price"/>
    </collection>
  </resultMap>

Note that there's <collection>two new properties, one is selectone column.
We finished in the query queryMyOrders, it will find its corresponding resultMapinside with subOrderItemListthis property according selectto the corresponding query. Queries will be a property value queries, we hope that the order id <id column="orderId" property="orderId"/>passed to the child order to query, so we use the columnproperty to specify resultMapthe incoming collectionline.

So here we will write a <select>, its corresponding id:

    <select id="getSubItems" parameterType="String" resultType="com.imooc.pojo.vo.MySubOrderItemVO">

      select
        oi.item_id as itemId,
        oi.item_name as itemName,
        oi.item_img as itemImg,
        oi.item_spec_name as itemSpecName,
        oi.buy_counts as buyCounts,
        oi.price as price
      from
        order_items oi
      where
        oi.order_id = #{orderId}

    </select>

We can also see that this is actually the second step of a method of content.

Published 385 original articles · won praise 326 · views 160 000 +

Guess you like

Origin blog.csdn.net/No_Game_No_Life_/article/details/104196346