如何做系列(1)- mybatis 如何实现分页?
<select id="" parameterType="" resultType="" resultMap="">
Select ROWNUM,ID,NAME FROM(Select ROWNUM as ROWNO, ID,NAME from CHANGED_CONTENT
<where>
<![CDATA[ROWNUM <= #{endRow}]]>
</where>
)
<where>
<![CDATA[ROWNO > #{startRow}]]>
</where>
</select>
然后我们在使用这个dao的时候,传入我们的分页的参数,就可以实现我们的分页需求了。其实很简单。
<span style="font-family: 微软雅黑; background-color: rgb(255, 255, 255);">    String countSql = "select count(1) from (" + sql    + ") tmp_count"  </span>
public class PagePlugin implements Interceptor {
    private static Logger log = Logger.getLogger("page plugin");
    private static Dialect dialectObject = null; // 数据库方言
    private static String pageSqlId = ""; // mybaits的数据库xml映射文件中需要拦截的ID(正则匹配)
    public Object intercept(Invocation ivk) throws Throwable {
        if (ivk.getTarget() instanceof RoutingStatementHandler) {
            log.info("com.dragon.dao.pulgin.mybatis.plugin.PagePlugin.intercept() enter*****************");
            RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk
                    .getTarget();
            BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper
                    .getValueByFieldName(statementHandler, "delegate");
            MappedStatement mappedStatement = (MappedStatement) ReflectHelper
                    .getValueByFieldName(delegate, "mappedStatement");
            /**
             * 方法1:通过ID来区分是否需要分页..*query.* 方法2:传入的参数是否有page参数,如果有,则分页,
             */
            if (mappedStatement.getId().matches(pageSqlId)) { // 拦截需要分页的SQL
                BoundSql boundSql = delegate.getBoundSql();
                Object parameterObject = boundSql.getParameterObject();// 分页SQL<select>中parameterType属性对应的实体参数,即Mapper接口中执行分页方法的参数,该参数不得为空
                if (parameterObject == null) {
                    //throw new NullPointerException("boundSql.getParameterObject() is null!");
                    return ivk.proceed();
                } else {
                    PageView pageView = null;
                    if (parameterObject instanceof PageView) { // 参数就是Pages实体
                        pageView = (PageView) parameterObject;
                    } else if (parameterObject instanceof Map) {
                        for (Entry entry : (Set<Entry>) ((Map) parameterObject).entrySet()) {
                            if (entry.getValue() instanceof PageView) {
                                pageView = (PageView) entry.getValue();
                                break;
                            }
                        }
                    } else { // 参数为某个实体,该实体拥有Pages属性
                        pageView = ReflectHelper.getValueByFieldType(
                                parameterObject, PageView.class);
                        if (pageView == null) {
                            return ivk.proceed();
                        }
                    }
                    String sql = boundSql.getSql();
                    PreparedStatement countStmt = null;
                    ResultSet rs = null;
                    try {
                        Connection connection = (Connection) ivk.getArgs()[0];
                        String countSql = "select count(1) from (" + sql
                                + ") tmp_count"; // 记录统计
                        countStmt = connection.prepareStatement(countSql);
                        ReflectHelper.setValueByFieldName(boundSql, "sql",
                                countSql);
                        DefaultParameterHandler parameterHandler = new DefaultParameterHandler(
                                mappedStatement, parameterObject, boundSql);
                        parameterHandler.setParameters(countStmt);
                        rs = countStmt.executeQuery();
                        Long count = 0L;
                        if (rs.next()) {
                            count = ((Number) rs.getObject(1)).longValue();
                        }
                        pageView.setRowCount(count);
                    } finally {
                        try {
                            rs.close();
                        } catch (Exception e) {
                        }
                        try {
                            countStmt.close();
                        } catch (Exception e) {
                        }
                    }
                    String pageSql = generatePagesSql(sql, pageView);
                    ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql); // 将分页sql语句反射回BoundSql.
                }
            }
        }
        return ivk.proceed();
    }
    /**
     * 根据数据库方言,生成特定的分页sql
     *
     * @param sql
     * @param page
     * @return
     */
    private String generatePagesSql(String sql, PageView page) {
        if (page != null && dialectObject != null) {
            //pageNow默认是从1,而已数据库是从0开始计算的.所以(page.getPageNow()-1)
            int pageNow = page.getPageNow();
            return dialectObject.getLimitString(sql, (pageNow <= 0 ? 0 : pageNow - 1)
                    * page.getPageSize(), page.getPageSize());
        }
        return sql;
    }
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
    public void setProperties(Properties p) {
        String dialect = ""; // 数据库方言
        dialect = p.getProperty("dialect");
        if (StringUtils.isBlank(dialect)) {
            try {
                throw new PropertyException("dialect property is not found!");
            } catch (PropertyException e) {
                log.error(e);
            }
        } else {
            try {
                dialectObject = (Dialect) Class.forName(dialect)
                        .getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                throw new RuntimeException(dialect + ", init fail!\n" + e);
            }
        }
        pageSqlId = p.getProperty("pageSqlId");//根据id来区分是否需要分页
        if (StringUtils.isBlank(pageSqlId)) {
            try {
                throw new PropertyException("pageSqlId property is not found!");
            } catch (PropertyException e) {
                log.error(e);
            }
        }
    }
}
public class OracleDialect extends Dialect {
    public boolean supportsLimit() {
        return true;
    }
    public boolean supportsLimitOffset() {
        return true;
    }
    public String getLimitString(String sql, int offset, String offsetPlaceholder, int limit, String limitPlaceholder) {
        sql = sql.trim();
        boolean isForUpdate = false;
        if (sql.toLowerCase().endsWith(" for update")) {
            sql = sql.substring(0, sql.length() - 11);
            isForUpdate = true;
        }
        StringBuffer pagingSelect = new StringBuffer(sql.length() + 100);
        if (offset > 0) {
            pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
        } else {
            pagingSelect.append("select * from ( ");
        }
        pagingSelect.append(sql);
        if (offset > 0) {
//			int end = offset+limit;
            String endString = offsetPlaceholder + "+" + limitPlaceholder;
            pagingSelect.append(" ) row_ ) where rownum_ <= " + endString + " and rownum_ > " + offsetPlaceholder);
        } else {
            pagingSelect.append(" ) where rownum <= " + limitPlaceholder);
        }
        if (isForUpdate) {
            pagingSelect.append(" for update");
        }
        return pagingSelect.toString();
    }
}
 <bean id="pagePlugin" class="com.xxxxx.pulgin.mybatis.plugin.PagePlugin">
        <property name="properties">
            <props>
                <prop key="dialect">com.dragon.dao.pulgin.jdbc.dialet.OracleDialect</prop>
                <prop key="pageSqlId">.*query.*</prop>
            </props>
        </property>
    </bean>
 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:spring/mybatis.xml" />
        <property name="plugins">
            <array>
                <ref bean="pagePlugin" /> 
            </array>
        </property>
        <property name="mapperLocations">
            <list>
                <!-- 自动匹配Mapper映射文件  -->
                <value>classpath:com/xxxxx/mapper/*-mapper.xml</value>
            </list>
        </property>
    </bean>
如何做系列(1)- mybatis 如何实现分页?的更多相关文章
- Mybatis Generator实现分页功能
		
Mybatis Generator实现分页功能 分类: IBATIS2013-07-17 17:03 882人阅读 评论(1) 收藏 举报 mybatisibatisgeneratorpage分页 众 ...
 - Mybatis第三方PageHelper分页插件原理
		
 欢迎关注公号:BiggerBoy,看更多文章 原文链接:https://mp.weixin.qq.com/s?__biz=MzUxNTQyOTIxNA==&mid=2247485158&a ...
 - Mybatis中的分页
		
Mybatis中有哪些分页方式? 数组分页:查询出全部数据,然后再list中截取需要的部分.(逻辑分页) 优点:效率高 缺点:占用内存比较高 sql分页:只从数据库中查询当前页的数据.(物理分 ...
 - SpringBoot+Mybatis配置Pagehelper分页插件实现自动分页
		
SpringBoot+Mybatis配置Pagehelper分页插件实现自动分页 **SpringBoot+Mybatis使用Pagehelper分页插件自动分页,非常好用,不用在自己去计算和组装了. ...
 - SpringBoot+Mybatis+PageHelper实现分页
		
SpringBoot+Mybatis+PageHelper实现分页 mybatis自己没有分页功能,我们可以通过PageHelper工具来实现分页,非常简单方便 第一步:添加依赖 <depend ...
 - SpringBoot集成Mybatis并具有分页功能PageHelper
		
SpringBoot集成Mybatis并具有分页功能PageHelper 环境:IDEA编译工具 第一步:生成测试的数据库表和数据 SET FOREIGN_KEY_CHECKS=0; ...
 - SpringBoot系列-整合Mybatis(注解方式)
		
目录 一.常用注解说明 二.实战 三.测试 四.注意事项 上一篇文章<SpringBoot系列-整合Mybatis(XML配置方式)>介绍了XML配置方式整合的过程,本文介绍下Spring ...
 - Mybatis的PageHelper分页插件的PageInfo的属性参数,成员变量的解释,以及页面模板
		
作者:个人微信公众号:程序猿的月光宝盒 //当前页 private int pageNum; //每页的数量 private int pageSize; //当前页的数量 private int si ...
 - 小白的springboot之路(十五)、mybatis的PageHelper分页插件使用
		
0.前言 用mybatis,那么分页必不可少,基本都是用PageHelper这个分页插件,好用方便: 1.实现 1.1.添加依赖: <!-- 3.集成 mybatis pagehelper--& ...
 
随机推荐
- delphi  流程单打印
			
1.添加声明 f_count1: double; 2.得到拆分页数量 // Modified by 884 2018-04-20 14:50:18 AM0057 with aqTpCount do b ...
 - CSIC_716_20191107【深拷贝、文件的编码解码、文件的打开模式】
			
深拷贝和浅拷贝 列表的拷贝,用copy方法浅拷贝,新列表和被拷贝列表的id是不一样的. list1 = [1, 'ss', (5, 6), ['p', 'w','M'], {'key1': 'valu ...
 - C/C++实现单向循环链表(尾指针,带头尾节点)
			
C语言实现单向循环链表,主要功能为空链表创建,链表初始化(头插法,尾插法),链表元素读取,按位置插入,(有序链表)按值插入,按位置删除,按值删除,清空链表,销毁链表. 单向循环链表和单向链表的区别:( ...
 - mysql索引原理深度解析
			
mysql索引原理深度解析 一.总结 一句话总结: mysql索引是b+树,因为b+树在范围查找.节点查找等方面优化 hash索引,完全平衡二叉树,b树等 1.数据库中最常见的慢查询优化方式是什么? ...
 - 怎样使用github?(转)
			
怎样使用github?(转) 转自: 怎样使用 GitHub? - 知乎https://www.zhihu.com/question/20070065 珊姗是个小太阳 ❤努力做最胖//bang的健身博 ...
 - maven项目依赖其他jar包的时候,idea运行没问题,java -jar 报错:java.lang.SecurityException: Invalid signature file digest
			
当项目依赖其他jar包的时候,打出的jar包执行出错,抛出这个异常. 原因:因为依赖jar包中的META-INF中有多余的.SF文件与当前jar包冲突, 解决方案 一 在打包前删除依赖jar包的.SF ...
 - Vue入坑——vue-cli(脚手架)目录结构认识
			
转载:https://my.oschina.net/u/3802541/blog/1809182 一.目录结构 |-- build // 项目构建 ...
 - Android Support 包的作用、用法
			
1, Android Support V4, V7, V13是什么?本质上就是三个java library. 2, 为什么要有support库?如果在低版本Android平台上开发一个应用程序,而应 ...
 - The Python Standard Library
			
The Python Standard Library¶ While The Python Language Reference describes the exact syntax and sema ...
 - F - GCD - Extreme (II) UVA - 11426
			
Given the value of N, you will have to find the value of G. The definition of G is given below: