Mybatis中分页存在的坑

时间:2019-05-22 16:01:22   收藏:0   阅读:112

站在巨人的肩膀上

https://www.cnblogs.com/esileme/p/7565184.html

环境:Spring 4.2.1 Mybatis 3.2.8 pagehelper 5.1.2

Mybatis官方教程:https://github.com/pagehelper/Mybatis-PageHelper/blob/d5947437cc6272cb3f1b186cadee74f1f8072cbb/wikis/zh/HowToUse.md

即可对数据进行分页处理。

Mybatis使用pageHelper分页出现的问题

在pageHelper的文档中,我们可以看到这样的提示分页插件不支持嵌套结果映射https://github.com/pagehelper/Mybatis-PageHelper/blob/d5947437cc6272cb3f1b186cadee74f1f8072cbb/wikis/zh/Important.md),由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。这时候对于一些嵌套查询来说使用通用pageHelper已经不能用了,因此需要我们通过手动分别查询分页数据以及分页数据的映射数据。

通过使用一个例子对pageHelper进行测试不兼容嵌套查询的结果映射:

 <resultMap type="java.util.Map" id="fatherMap">
        <result column="orderId" property="orderId" />
        <result column="payment" property="payment" />
        <result column="buyer_nick" property="buyerNick" />
        <result column="shipping_code" property="shippingCode" />
        <result column="state" property="state" />
    </resultMap>

    <resultMap type="java.util.Map" id="orderMap" extends="fatherMap">

        <collection property="items" javaType="ArrayList" resultMap="itemMap" />

    </resultMap>

    <select id="getOrdersByUserId" resultMap="orderMap">

        SELECT o.order_id AS orderId,o.payment ,o.buyer_nick,o.shipping_code
        ,o.status AS orderState,i.title ,i.price FROM tb_order AS o,tb_item AS
        i,tb_order_item AS oi WHERE o.user_id=#{userId} AND
        oi.order_id=o.order_id AND i.id=oi.item_id

    </select>
   /*Service层代码*/
    public List<Map<String, Object>> getOrdersByUserId(String userId) {

        PageHelper.startPage(1, 2);
        List<Map<String, Object>> list = orderMapper.getOrdersByUserId(userId);
        return list;

    }

通过嵌套查询返回一个Map对象并嵌套了另一个表中的多条数据(List集合),在取出数据后,可以看到这样的结果:

技术分享图片

可以发现,pageHelper对我们的子数据进行了分页,我们要两条数据且只是出现了一条数据,这个时候,就只有通过分别查询来取出数据了。

首先,对订单数据不进行关联查询,先把数据取出来,然后根据取出来的订单对象,再把关联的信息查出来,这样就可以使用pageHelper来进行操作了。在Service层的代码如下:

    public List<Map<String, Object>> getAnotherOrdersByUserId(String userId) {
        PageHelper.startPage(1, 2);
        List<Map<String, Object>> orderMaps = orderMapper.getAnotherOrdersByUserId(userId);
        for (Map<String, Object> map : orderMaps) {
            String orderId = (String) map.get("orderId");
            List<Map<String, Object>> items = orderMapper.getItems(orderId);
            map.put("items", items);
        }
        PageInfo pageInfor = new PageInfo(orderMaps);
        System.out.println(pageInfor.getPageNum());
        System.out.println(pageInfor.getTotal());

        return orderMaps;
    }

mapper的代码:

<select id="getAnotherOrdersByUserId" resultMap="fatherMap">

    SELECT o.order_id AS orderId,o.payment ,o.buyer_nick,o.shipping_code
    ,o.status AS orderState FROM tb_order AS o WHERE o.user_id=#{userId}

</select>


<select id="getItems" resultMap="itemMap">

    SELECT item.title ,item.price FROM tb_order_item AS oi ,tb_item AS item
    WHERE oi.order_id=#{orderId} AND oi.item_id=item.id

</select>

这样通过分别查询就可以避免了pageHelper的联合查询的问题。

正确的数据显示:

技术分享图片

Demo:https://github.com/esileme/MybatisPager

PageHelper分页原理

在Mybatis中,提供了一个Interceptor接口,Mybatis的PageInterceptor类实现了Interceptor接口,在这个接口中,MyBatis允许我们拦截四个方法(ParameterHandler、ResultSetHandler、StatementHandler、Executor),可以对这四个方法进行拦截并实现相应的操作。

我们可以自定义实现Interceptor方式对Mybatis返回为Map的对象进行数据库数据与pojo对象映射的操作:

原文:https://www.cnblogs.com/longxok/p/10906085.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!