Mybatis非侵入式的分页机制

来源:互联网 发布:剑三毒哥妖孽捏脸数据 编辑:程序博客网 时间:2024/05/20 00:37

 

传统分页

需将 limit  rownum top 等分页关键字带入sql,而且还需要人为执行2次sql(一次count查询,一次数据查询),才能组装最终所需数据。

弊端:对sql的入侵太强,如有良好的框架支持还好,如需手动处理分页堪称体力活。

 

非侵入式分页

基于hibernate的思想,我在mybatis源码中嵌入了threadlocal的机制,在执行目前sql前去拦截select语句,根据threadlocal中的分页需求,临时更改select语句,实现分页。

好处:在业务代码中,无需关注分页语句,只需加入简单的开关,就可实现count、分页查询

弊端:目前只支持mysql  oracle, 对复杂的多重嵌套的 union 语句支持不好

 

默认启用mysql分页机制,如需切到oracle,请在 classpath下添加配置文件:

dialect.properties

配置信息如下:

db_dialect =com.brojade.pub.plugin.dialect. OracleDialect4Paging

 

具体修改了以下源码:

_org.apache.ibatis.cache.CacheKey

_org.apache.ibatis.executor.BaseExecutor

_org.apache.ibatis.executor.CachingExecutor

_org.apache.ibatis.executor.Executor

_org.apache.ibatis.executor.statement.PreparedStatementHandler

_org.apache.ibatis.mapping.BoundSql

 

的使用方法举例:

    // 初始化并注入分布参数对象(此行代码会在拦截器中统一执行)

    ThreadPagingUtil.putPageparam(PageParam.initWithPageIndex(2,10,"create_time", PageParam.OrderByType.DESC));

    //开启分页(此行代码需要在分页的查询方法前调用)

    ThreadPaging.turnOn();  

    //构造查询语句

    session = sqlSessionFactory.openSession();

    blogMapper = session.getMapper(BlogMapper.class);

    BlogExample be = new BlogExample();

    be.createCriteria().andContextLike("%%");

    //在加入以上2行代码后,此时返回的一个PageList对象,需要强制转型

    PageList<Blog>  blogList=

(PageList<Blog>)blogMapper.selectByExample(be);

 

 

api概述

1、ThreadPagingUtil.putPageparam(PageParam  pageParam)

会在本地线程类对象中放入一个分页参数对象,PageParam对象有6种构造方式,可根据自己实际需要来选择(在三个框架整合后,如果是前端的查询分页请求,我们在struts拦截器层统一调用此方法,而不需要开发人员在action层或service层调用)

 

/**

            * 以偏移量的形式查询, 此方法返回的pageList中不包含上一页、下一页、记录总数等信息

            * @param start  开始位置

            * @param limit  偏移量

            * @return

            */

           public static PageParam initWithOffset(Integer start, Integerlimit)

 

 

           /**

            * 以页码的形式查询 

            * @param targetPage 目标页码

            * @param pageSize  每页显示数

            * @return

            */

           publicstatic PageParam initWithPageIndex(Integer targetPage, Integer pageSize)

 

 

           /**

            * 以偏移量的形式查询 

            * @param start 开始位置

            * @param limit 偏移量

            * @param needCount 是否需要count查询 ,默认为否

            * @return

            */

           publicstatic PageParam initWithOffset(Integer start, Integer limit, BooleanneedCount)

 

           /**

            * 以偏移量的形式查询

            * @param start 开始位置

            * @param limit 偏移量

            * @param orderByColumn 排序的表字段名

            * @param orderByType 排序方式 默认为 asc

            * @return

            */

           publicstatic PageParam initWithOffset(Integer start, Integer limit, StringorderByColumn, OrderByType orderByType)

 

 

           /**

            * 以页码的形式查询

            * @param targetPage 目标页码

            * @param pageSize 每页显示数

            * @param orderByColumn 排序的表字段名

            * @param orderByType 排序方式 默认为 asc

            * @return

            */

           publicstatic PageParam initWithPageIndex(Integer targetPage, Integer pageSize, StringorderByColumn, OrderByType orderByType)

 

 

2、ThreadPagingUtil.turnOn()

通知下一次查询要使用分页。此时在调用查询类操作的时候,mybatis会根据pageParam的相关参数来查询对应的数据信息,并且封闭成PageList对象(ArrayList的子类)返回。

 

 

关于PageParam

PageParam对象的生成有2种方式:

1、  根据偏移量

即 start 、limit方式。

这种方式默认是不会进行count查询,即返回的PageList对象中不包含记录总数、是否有上一页、下一页等参数信息。如需要返回,则要在初始化时转入needCount参数为true

 

2、  根据页码

此方式是最常用的,需要转入pageIndex、pageSize即可,排序参数可选。

返回的是一完整的PageList对象。

 

 

 

0 0
原创粉丝点击