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>