问题描述
在使用 Mybatis-PageHelper 进行分页的时候,查询出来的结果集是一个嵌套的结果,此时发现查询出来的记录数与设置的 pagesize 明显不符合。
问题还原
我的 mapper 实现时这么写的 ,
<resultMap id="myOrdersVo" type="com.cjervin.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.cjervin.vo.MySubOrderItemVO">
<result column="itemId" property="itemId"/>
<result column="itemName" property="itemName"/>
<result column="itemImg" property="itemImg"/>
<result column="itemSpecName" property="itemSpecName"/>
<result column="buyCounts" property="buyCounts"/>
<result column="price" property="price"/>
</collection>
</resultMap>
<select id="queryMyOrderList" parameterType="map" resultMap="myOrdersVo">
SELECT
o.id AS orderId,
o.created_time AS createdTime,
o.pay_method AS payMethod,
o.real_pay_amount AS realPayAmount,
o.post_amount AS postAmount,
os.order_status AS orderStatus,
o.is_comment AS isComment,
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 o
LEFT JOIN order_status os ON o.id = os.order_id
LEFT JOIN order_items oi ON o.id = oi.order_id
WHERE o. user_id = #{paramMap.userId}
AND o.is_delete = 0
<if test="paramMap.orderStatus != null">
AND os.order_status = #{paramMap.orderStatus}
</if>
ORDER BY o.updated_time ASC
</select>
MyOrdersVO:
public class MyOrdersVO {
private String orderId;
private Date createdTime;
private Integer payMethod;
private Integer realPayAmount;
private Integer postAmount;
private Integer isComment;
private Integer orderStatus;
private List<MySubOrderItemVO> subOrderItemList;
MySubOrderItemVO:
public class MySubOrderItemVO {
private String itemId;
private String itemImg;
private String itemName;
private String itemSpecName;
private Integer buyCounts;
private Integer price;
可以看到,xml 里面配置的一个叫做 myOrdersVo 的 resultMap 下面还嵌套了一个collection子结果集。
servcice:
@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> orderList = ordersMapperCustom.queryMyOrderList(map);
return setterPagedGrid(orderList,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;
}
controller:
@PostMapping("/query")
public JSONResult query(@RequestParam("userId") String userId,@RequestParam("orderStatus")Integer orderStatus,
@RequestParam(value ="page",defaultValue = "1")Integer page,
@RequestParam(value ="pageSize",defaultValue = "10")Integer pageSize){
PagedGridResult pagedGridResult = myOrderService.queryMyOrders(userId, orderStatus, page, pageSize);
return JSONResult.ok(pagedGridResult);
}
然后使用 postman 来测试,
我们看到返回的结果只有三条,与之前传进去的4明显有偏差,但是展开后如果按照子结果集的数量算的话是可以对上的
这与我们的期望不符,我们希望的是,父结果集可以展示4条!!
问题解决:
Mybatis-PageHelper 将代码托管在 github ,我们去看一眼是否有解决的办法,以下是截图:
分页插件不支持嵌套结果映射,那只能自己想办法了
既然一次 select 不行,那我们把嵌套的那部分抽取出来,查询两次应该可以解决问题
<resultMap id="myOrdersVo" type="com.cjervin.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.cjervin.vo.MySubOrderItemVO">
<result column="itemId" property="itemId"/>
<result column="itemName" property="itemName"/>
<result column="itemImg" property="itemImg"/>
<result column="itemSpecName" property="itemSpecName"/>
<result column="buyCounts" property="buyCounts"/>
<result column="price" property="price"/>
</collection>
</resultMap>
<select id="getSubItems" parameterType="string" resultType="com.cjervin.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>
<select id="queryMyOrderList" parameterType="map" resultMap="myOrdersVo">
SELECT
o.id AS orderId,
o.created_time AS createdTime,
o.pay_method AS payMethod,
o.real_pay_amount AS realPayAmount,
o.post_amount AS postAmount,
os.order_status AS orderStatus,
o.is_comment AS isComment
FROM orders o
LEFT JOIN order_status os ON o.id = os.order_id
WHERE o. user_id = #{paramMap.userId}
AND o.is_delete = 0
<if test="paramMap.orderStatus != null">
AND os.order_status = #{paramMap.orderStatus}
</if>
ORDER BY o.updated_time ASC
</select>
我们同过 collection 标签 的 select 标签可以在一个查询里嵌套一次查询, 通过 collection 标签的 column 标签做一个值传递。可以解决上述问题,接着来测试一下:
问题解决!
来源:oschina
链接:https://my.oschina.net/u/4074923/blog/4263141