mybatis Spring MVC添加分页拦截器

网上有很多封装的mybatis 分页拦截器,但是看起来都比较乱,不能直接套用,在这里贴出项目中的分页源码出来供大家参考。

Controller 层:

@RequestMapping("/channelList")
    public String channelList(HttpServletRequest request,AppMarket appMarket,Model model){
        String pageNo = request.getParameter("pageNo");
        Page page = new Page();
        if (StringUtils.isNotBlank(pageNo)) {
            page.setPageNo(Integer.parseInt(pageNo));
        }
        
        RowBounds rowBounds = PageTools.getRowBounds(page);
        appMarket = (AppMarket) StringTools.spacialCharForHtml(appMarket);
        List<AppMarket> marketList = appMarketService.selectMarkets(appMarket, rowBounds);
        for (int i = 0; i < marketList.size(); i++) {
            marketList.set(i, (AppMarket) StringTools.spacialCharForHtml(marketList.get(i)));
        }
        model.addAttribute("marketName",appMarket.getMarketName());
        model.addAttribute("marketList",marketList);
        long totalCount = appMarketService.selectTotalCount();
        page.setTotalRecordNum(totalCount);
        model.addAttribute("page",page);
        return "channel/channel_list";
    }

先定义好page的属性,再用RowsBounds 类进行数据封装。

Page 类:

public class Page implements Serializable{
    
    private static final long serialVersionUID = 5953682584953355175L;

    private Integer pageSize=10;
    
    private Integer pageNo=1;
    
    private long totalPageNum;
    
    private long totalRecordNum;
    
    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getPageNo() {
        return pageNo;
    }

    public void setPageNo(Integer pageNo) {
        this.pageNo = pageNo;
    }

    public Long getTotalPageNum() {
        return (totalRecordNum -1)/pageSize +1;
    }

    public Long getTotalRecordNum() {
        return totalRecordNum;
    }

    public void setTotalRecordNum(Long totalRecordNum) {
        this.totalRecordNum = totalRecordNum;
    }
    
}
PageTools.getRowBounds(page) 方法:
package com.ijiami.appdata.common.page;

import org.apache.ibatis.session.RowBounds;

public class PageTools{

    public static RowBounds getRowBounds(Page page) {
        if(page.getPageNo()==null||page.getPageSize()==null||page.getPageNo()==0||page.getPageSize()==0){
            page.setPageNo(1);
            page.setPageSize(10);
        }
        return new RowBounds((page.getPageNo()-1)*page.getPageSize(), page.getPageSize());
    }
    
}

Service 层很简单,直接调用Maper:

    @Override
    public List<AppMarket> selectMarkets(AppMarket record, RowBounds r) {
        return appMarketMapper.selectMarkets(record, r);
    }

Maper 对应mybatis 配置:

  <select id="selectMarkets" parameterType="com.ijiami.appdata.model.AppMarket" resultMap="BaseResultMap">
    select 
    <include refid="Part_Column_List" />
    from app_market where 1 = 1
    <if test="marketName != null">
        and market_name LIKE  '%${marketName}%'
    </if>
  </select>

最重要的就是接下来的拦截器,将mybatis 将要执行的sql进行拦截封装:

package com.ijiami.appdata.common.page.interceptor;


import java.sql.Connection;
import java.util.Properties;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
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;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;

import com.ijiami.appdata.common.page.dialect.Dialect;
import com.ijiami.appdata.common.page.dialect.MySqlDialect;
import com.ijiami.appdata.common.page.dialect.OracleDialect;


@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class})})
public class PaginationInterceptor implements Interceptor{

    
    private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory(); 
    private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
    private static final ReflectorFactory DEFAULT_REFLECTOR_FACTORY = new DefaultReflectorFactory();
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();
        MetaObject metaStatementHandler = MetaObject.forObject(statementHandler,DEFAULT_OBJECT_FACTORY,DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_REFLECTOR_FACTORY);
        RowBounds rowBounds = (RowBounds)metaStatementHandler.getValue("delegate.rowBounds");
        if(rowBounds == null || rowBounds == RowBounds.DEFAULT){
            return invocation.proceed();
        }
        Configuration configuration = (Configuration)metaStatementHandler.getValue("delegate.configuration");
        Dialect.Type databaseType  = null;
        try{
            databaseType = Dialect.Type.valueOf(configuration.getVariables().getProperty("dialect").toUpperCase());
        } catch(Exception e){
            //ignore
        }
        if(databaseType == null){
            throw new RuntimeException("the value of the dialect property in configuration.xml is not defined : " + configuration.getVariables().getProperty("dialect"));
        }
        Dialect dialect = null;
        switch(databaseType){
            case MYSQL:
                dialect = new MySqlDialect();
                break;
            case ORACLE:
                dialect = new OracleDialect();
                break;
            default:
                dialect = new MySqlDialect();
                
        }
        
        String originalSql = (String)metaStatementHandler.getValue("delegate.boundSql.sql");
        metaStatementHandler.setValue("delegate.boundSql.sql", dialect.getLimitString(originalSql, rowBounds.getOffset(), rowBounds.getLimit()) );
        metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET );
        metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT );
        System.out.println("key="+boundSql.getSql());
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }

}

 

 

 

posted @ 2017-02-16 11:33  phyxis_xu  阅读(2750)  评论(0编辑  收藏  举报