博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PageHelper在Mybatis中的使用
阅读量:5296 次
发布时间:2019-06-14

本文共 5450 字,大约阅读时间需要 18 分钟。

环境: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

  • 加入pageHelper依赖

    com.github.pagehelper
    pagehelper
    5.1.2
  • 在Mybatis-config.xml中配置pageHelper的拦截器

  • 调用startPage()分页方法,在获取数据后将数据放到PageInfo对象中。

    PageHelper.startPage(page, pageSize);  List
    > list = itemMapper.getItems(); PageInfo
    > pageInfor = new PageInfo
    >(list);

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

Mybatis使用pageHelper分页出现的问题

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

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

/*Service层代码*/ public List
> getOrdersByUserId(String userId) { PageHelper.startPage(1, 2); List
> list = orderMapper.getOrdersByUserId(userId); return list; }

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

1220001-20170921162141384-1657458077.png

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

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

public List
> getAnotherOrdersByUserId(String userId) { PageHelper.startPage(1, 2); List
> orderMaps = orderMapper.getAnotherOrdersByUserId(userId); for (Map
map : orderMaps) { String orderId = (String) map.get("orderId"); List
> 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的代码:

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

正确的数据显示:

1220001-20170921162154431-895434919.png

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

PageHelper分页原理

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

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

  • 在Mybatis-config.xml中配置

  • code

    package com.yl.page.intercpter;import java.sql.Statement;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.Set;import org.apache.ibatis.executor.resultset.ResultSetHandler;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Plugin;import org.apache.ibatis.plugin.Signature;@Intercepts(@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = { Statement.class }))public class CameHumpIntercpter implements Interceptor {    public Object intercept(Invocation invocation) throws Throwable {        List values = (List) invocation.proceed();        for (Object object : values) {            if (object instanceof Map) {                processMap((Map) object);            } else {                break;            }        }        return values;    }    public Object plugin(Object target) {        return Plugin.wrap(target, this);    }    // 获取配置参数    public void setProperties(Properties properties) {    }    private void processMap(Map
    map) { Set
    keySet = new HashSet
    (map.keySet()); for (String key : keySet) { if ((key.charAt(0) >= 'A' && key.charAt(0) <= 'Z') || key.indexOf("_") >= 0) { Object value = map.get(key); map.remove(key); map.put(undelineToNomall(key), value); } } } public String undelineToNomall(String inputString) { StringBuilder buder = new StringBuilder(); boolean nextUpperCase = false; for (int i = 0; i < inputString.length(); i++) { char c = inputString.charAt(i); if (c == '_') { if (buder.length() > 0) { nextUpperCase = true; } } else { if (nextUpperCase) { buder.append(Character.toUpperCase(c)); nextUpperCase = false; } else { buder.append(Character.toLowerCase(c)); } } } return buder.toString(); }}

转载于:https://www.cnblogs.com/esileme/p/7565184.html

你可能感兴趣的文章
Mybatis生成resulteMap时的注意事项
查看>>
jquery-jqzoom 插件 用例
查看>>
1007. Maximum Subsequence Sum (25)
查看>>
iframe的父子层跨域 用了百度的postMessage()方法
查看>>
图片生成缩略图
查看>>
动态规划 例子与复杂度
查看>>
查看oracle数据库的连接数以及用户
查看>>
【数据结构】栈结构操作示例
查看>>
中建项目环境迁移说明
查看>>
三.野指针和free
查看>>
activemq5.14+zookeeper3.4.9实现高可用
查看>>
TCP/IP详解学习笔记(3)IP协议ARP协议和RARP协议
查看>>
简单【用户输入验证】
查看>>
python tkinter GUI绘制,以及点击更新显示图片
查看>>
HDU4405--Aeroplane chess(概率dp)
查看>>
CS0103: The name ‘Scripts’ does not exist in the current context解决方法
查看>>
20130330java基础学习笔记-语句_for循环嵌套练习2
查看>>
Spring面试题
查看>>
窥视SP2010--第一章节--SP2010开发者路线图
查看>>
MVC,MVP 和 MVVM 的图示,区别
查看>>