Java简单实现SpringMVC+MyBatis分页插件
1.封装分页Page类
packagecom.framework.common.page.impl; importjava.io.Serializable; importcom.framework.common.page.IPage; /** * * * */ publicabstractclassBasePageimplementsIPage,Serializable{ /** * */ privatestaticfinallongserialVersionUID=-3623448612757790359L; publicstaticintDEFAULT_PAGE_SIZE=20; privateintpageSize=DEFAULT_PAGE_SIZE; privateintcurrentResult; privateinttotalPage; privateintcurrentPage=1; privateinttotalCount=-1; publicBasePage(intcurrentPage,intpageSize,inttotalCount){ this.currentPage=currentPage; this.pageSize=pageSize; this.totalCount=totalCount; } publicintgetTotalCount(){ returnthis.totalCount; } publicvoidsetTotalCount(inttotalCount){ if(totalCount<0){ this.totalCount=0; return; } this.totalCount=totalCount; } publicBasePage(){ } publicintgetFirstResult(){ return(this.currentPage-1)*this.pageSize; } publicvoidsetPageSize(intpageSize){ if(pageSize<0){ this.pageSize=DEFAULT_PAGE_SIZE; return; } this.pageSize=pageSize; } publicintgetTotalPage(){ if(this.totalPage<=0){ this.totalPage=(this.totalCount/this.pageSize); if((this.totalPage==0)||(this.totalCount%this.pageSize!=0)){ this.totalPage+=1; } } returnthis.totalPage; } publicintgetPageSize(){ returnthis.pageSize; } publicvoidsetPageNo(intcurrentPage){ this.currentPage=currentPage; } publicintgetPageNo(){ returnthis.currentPage; } publicbooleanisFirstPage(){ returnthis.currentPage<=1; } publicbooleanisLastPage(){ returnthis.currentPage>=getTotalPage(); } publicintgetNextPage(){ if(isLastPage()){ returnthis.currentPage; } returnthis.currentPage+1; } publicintgetCurrentResult(){ this.currentResult=((getPageNo()-1)*getPageSize()); if(this.currentResult<0){ this.currentResult=0; } returnthis.currentResult; } publicintgetPrePage(){ if(isFirstPage()){ returnthis.currentPage; } returnthis.currentPage-1; } }
packagecom.framework.common.page.impl; importjava.util.List; /** * * * */ publicclassPageextendsBasePage{ /** * */ privatestaticfinallongserialVersionUID=-970177928709377315L; publicstaticThreadLocal<Page>threadLocal=newThreadLocal<Page>(); privateList<?>data; publicPage(){ } publicPage(intcurrentPage,intpageSize,inttotalCount){ super(currentPage,pageSize,totalCount); } publicPage(intcurrentPage,intpageSize,inttotalCount,List<?>data){ super(currentPage,pageSize,totalCount); this.data=data; } publicList<?>getData(){ returndata; } publicvoidsetData(List<?>data){ this.data=data; } }
2.封装分页插件
packagecom.framework.common.page.plugin; importjava.sql.Connection; importjava.sql.PreparedStatement; importjava.sql.ResultSet; importjava.sql.SQLException; importjava.util.List; importjava.util.Properties; importjavax.xml.bind.PropertyException; importorg.apache.commons.lang3.StringUtils; importorg.apache.ibatis.executor.ErrorContext; importorg.apache.ibatis.executor.ExecutorException; importorg.apache.ibatis.executor.statement.BaseStatementHandler; importorg.apache.ibatis.executor.statement.RoutingStatementHandler; importorg.apache.ibatis.mapping.BoundSql; importorg.apache.ibatis.mapping.MappedStatement; importorg.apache.ibatis.mapping.ParameterMapping; importorg.apache.ibatis.mapping.ParameterMode; importorg.apache.ibatis.plugin.Interceptor; importorg.apache.ibatis.plugin.Intercepts; importorg.apache.ibatis.plugin.Invocation; importorg.apache.ibatis.plugin.Plugin; importorg.apache.ibatis.reflection.MetaObject; importorg.apache.ibatis.reflection.property.PropertyTokenizer; importorg.apache.ibatis.scripting.xmltags.ForEachSqlNode; importorg.apache.ibatis.session.Configuration; importorg.apache.ibatis.type.TypeHandler; importorg.apache.ibatis.type.TypeHandlerRegistry; importcom.framework.common.page.impl.Page; importcom.framework.common.utils.ReflectUtil; /** * * * */ @Intercepts({@org.apache.ibatis.plugin.Signature(type=org.apache.ibatis.executor.statement.StatementHandler.class,method="prepare",args={Connection.class})}) publicclassPagePluginimplementsInterceptor{ privateStringdialect=""; privateStringpageSqlId=""; @Override publicObjectintercept(Invocationinvocation)throwsThrowable{ if(invocation.getTarget()instanceofRoutingStatementHandler){ BaseStatementHandlerdelegate=(BaseStatementHandler)ReflectUtil .getValueByFieldName( (RoutingStatementHandler)invocation.getTarget(), "delegate"); MappedStatementmappedStatement=(MappedStatement)ReflectUtil .getValueByFieldName(delegate, "mappedStatement"); Pagepage=Page.threadLocal.get(); if(page==null){ page=newPage(); Page.threadLocal.set(page); } if(mappedStatement.getId().matches(".*("+this.pageSqlId+")$")&&page.getPageSize()>0){ BoundSqlboundSql=delegate.getBoundSql(); ObjectparameterObject=boundSql.getParameterObject(); Stringsql=boundSql.getSql(); StringcountSqlId=mappedStatement.getId().replaceAll(pageSqlId,"Count"); MappedStatementcountMappedStatement=null; if(mappedStatement.getConfiguration().hasStatement(countSqlId)){ countMappedStatement=mappedStatement.getConfiguration().getMappedStatement(countSqlId); } StringcountSql=null; if(countMappedStatement!=null){ countSql=countMappedStatement.getBoundSql(parameterObject).getSql(); }else{ countSql="SELECTCOUNT(1)FROM("+sql+")T_COUNT"; } inttotalCount=0; PreparedStatementcountStmt=null; ResultSetresultSet=null; try{ Connectionconnection=(Connection)invocation.getArgs()[0]; countStmt=connection.prepareStatement(countSql); BoundSqlcountBoundSql=newBoundSql(mappedStatement.getConfiguration(),countSql,boundSql.getParameterMappings(),parameterObject); setParameters(countStmt,mappedStatement,countBoundSql,parameterObject); resultSet=countStmt.executeQuery(); if(resultSet.next()){ totalCount=resultSet.getInt(1); } }catch(Exceptione){ throwe; }finally{ try{ if(resultSet!=null){ resultSet.close(); } }finally{ if(countStmt!=null){ countStmt.close(); } } } page.setTotalCount(totalCount); ReflectUtil.setValueByFieldName(boundSql,"sql",generatePageSql(sql,page)); } } returninvocation.proceed(); } /** *对SQL参数(?)设值,参考org.apache.ibatis.executor.parameter.DefaultParameterHandler *@paramps *@parammappedStatement *@paramboundSql *@paramparameterObject *@throwsSQLException */ privatevoidsetParameters(PreparedStatementps,MappedStatementmappedStatement,BoundSqlboundSql,ObjectparameterObject)throwsSQLException{ ErrorContext.instance().activity("settingparameters").object(mappedStatement.getParameterMap().getId()); List<ParameterMapping>parameterMappings=boundSql.getParameterMappings(); if(parameterMappings!=null){ Configurationconfiguration=mappedStatement.getConfiguration(); TypeHandlerRegistrytypeHandlerRegistry=configuration.getTypeHandlerRegistry(); MetaObjectmetaObject=parameterObject==null?null:configuration.newMetaObject(parameterObject); for(inti=0;i<parameterMappings.size();i++){ ParameterMappingparameterMapping=parameterMappings.get(i); if(parameterMapping.getMode()!=ParameterMode.OUT){ Objectvalue; StringpropertyName=parameterMapping.getProperty(); PropertyTokenizerprop=newPropertyTokenizer(propertyName); if(parameterObject==null){ value=null; }elseif(typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())){ value=parameterObject; }elseif(boundSql.hasAdditionalParameter(propertyName)){ value=boundSql.getAdditionalParameter(propertyName); }elseif(propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX)&&boundSql.hasAdditionalParameter(prop.getName())){ value=boundSql.getAdditionalParameter(prop.getName()); if(value!=null){ value=configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length())); } }else{ value=metaObject==null?null:metaObject.getValue(propertyName); } TypeHandlertypeHandler=parameterMapping.getTypeHandler(); if(typeHandler==null){ thrownewExecutorException("TherewasnoTypeHandlerfoundforparameter"+propertyName+"ofstatement"+mappedStatement.getId()); } typeHandler.setParameter(ps,i+1,value,parameterMapping.getJdbcType()); } } } } /** *根据数据库方言,生成特定的分页sql *@paramsql *@parampage *@return */ privateStringgeneratePageSql(Stringsql,Pagepage){ if(page!=null&&StringUtils.isNotBlank(dialect)){ StringBufferpageSql=newStringBuffer(); if("mysql".equals(dialect)){ pageSql.append(sql); pageSql.append("LIMIT"+page.getCurrentResult()+","+page.getPageSize()); }elseif("oracle".equals(dialect)){ pageSql.append("SELECT*FROM(SELECTTMP_TB.*,ROWNUMROW_IDFROM("); pageSql.append(sql); pageSql.append(")ASTMP_TBWHEREROWNUM<="); pageSql.append(page.getCurrentResult()+page.getPageSize()); pageSql.append(")WHEREROW_ID>"); pageSql.append(page.getCurrentResult()); } returnpageSql.toString(); }else{ returnsql; } } @Override publicObjectplugin(Objecttarget){ returnPlugin.wrap(target,this); } @Override publicvoidsetProperties(Propertiesproperties){ try{ if(StringUtils.isEmpty(this.dialect=properties .getProperty("dialect"))){ thrownewPropertyException("dialectpropertyisnotfound!"); } if(StringUtils.isEmpty(this.pageSqlId=properties .getProperty("pageSqlId"))){ thrownewPropertyException("pageSqlIdpropertyisnotfound!"); } }catch(PropertyExceptione){ e.printStackTrace(); } } }
3.MyBatis配置文件:mybatis-config.xml
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTDSQLMapConfig3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <plugins> <plugininterceptor="com.framework.common.page.plugin.PagePlugin"> <propertyname="dialect"value="mysql"/> <propertyname="pageSqlId"value="ByPage"/> </plugin> </plugins> </configuration>
4.分页拦截器
packagecom.framework.common.page.interceptor; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importorg.apache.commons.lang3.math.NumberUtils; importorg.springframework.web.servlet.ModelAndView; importorg.springframework.web.servlet.handler.HandlerInterceptorAdapter; importcom.framework.common.page.impl.Page; /** * *14* */ publicclassPageInterceptorextendsHandlerInterceptorAdapter{ @Override publicvoidpostHandle(HttpServletRequestrequest, HttpServletResponseresponse,Objecthandler, ModelAndViewmodelAndView)throwsException{ super.postHandle(request,response,handler,modelAndView); Pagepage=Page.threadLocal.get(); if(page!=null){ request.setAttribute("page",page); } Page.threadLocal.remove(); } @Override publicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse,Objecthandler)throwsException{ StringpageSize=request.getParameter("pageSize"); StringpageNo=request.getParameter("pageNo"); Pagepage=newPage(); if(NumberUtils.isNumber(pageSize)){ page.setPageSize(NumberUtils.toInt(pageSize)); } if(NumberUtils.isNumber(pageNo)){ page.setPageNo(NumberUtils.toInt(pageNo)); } Page.threadLocal.set(page); returntrue; } }
5.Spring配置
<!--=================================================================== -Loadpropertyfile -===================================================================--> <context:property-placeholderlocation="classpath:application.properties"/> <beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean"> <propertyname="dataSource"ref="dataSource"/> <propertyname="configLocation"value="classpath:mybatis-config.xml"/> <propertyname="mapperLocations"> <list> <value>classpath:/com/framework/mapper/**/*Mapper.xml</value> </list> </property> </bean> <!--=================================================================== -通过扫描的模式,扫描目录下所有的dao,根据对应的mapper.xml为其生成代理类 -===================================================================--> <beanid="mapperScannerConfigurer"class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <propertyname="basePackage"value="com.framework.dao"/> <propertyname="processPropertyPlaceHolders"value="true"/> <propertyname="sqlSessionFactoryBeanName"value="sqlSessionFactory"/> </bean>
6.SpringMVC配置拦截器
<!--分页拦截器--> <beanid="pageInterceptor"class="com.framework.common.page.interceptor.PageInterceptor"></bean> <!--配置拦截器--> <beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <propertyname="interceptors"> <list> <refbean="pageInterceptor"/> </list> </property> </bean>