spring+mybatis 物理分页

Posted wangpeng047

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring+mybatis 物理分页相关的知识,希望对你有一定的参考价值。

新项目用的spring mvc 和 mybatis 分页。研究了一下,集众家之长然后形成现在的项目。我把分页部分剥离出来与大家分享。如有不妥的地方欢迎交流拍砖。

单独做了一个小项目,放到了下载区,如果有用到的朋友可以去下载。

本项目采用了拦截器,就是mybaits自带的plus功能。将每次select操作都进行拦截。

项目架构如下:


1:首先从cotroller层出发,啥也不说,上代码。这个最实惠

[java] view plain copy print ?
  1. package com.flydreamer.controller;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.   
  9. import org.springframework.beans.factory.annotation.Autowired;  
  10. import org.springframework.stereotype.Controller;  
  11. import org.springframework.web.bind.annotation.RequestMapping;  
  12. import org.springframework.web.servlet.ModelAndView;  
  13.   
  14. import com.flydreamer.logic.UserService;  
  15. import com.flydreamer.page.Page;  
  16. import com.flydreamer.page.PageContext;  
  17. import com.flydreamer.util.web.HandlerResult;  
  18.   
  19. @Controller  
  20. @RequestMapping("/user.do")  
  21. public class UserController   
  22.       
  23.     @Autowired  
  24.     private UserService userService;  
  25.       
  26.     @RequestMapping(params = ("method=list"))  
  27.     public ModelAndView listAll(HttpServletRequest request,HttpServletResponse response)   
  28.           
  29.         //可以将分页参数获取封装,已达到更好的复用效果。  
  30.         //page=2&pageSize=10&totalPages=19&totalRows=188  
  31.         String pagec = request.getParameter("page");   
  32.         String pageSize = request.getParameter("pageSize");   
  33.         String totalPages = request.getParameter("totalPages");   
  34.         String totalRows = request.getParameter("totalRows");   
  35.           
  36.         //方法1:将分页参数直接放到mapper接口函数参数中,也可在对象中定义名字为page的属性,反射一样可以得到  
  37.         //后台连接直接获取   
  38.         //Page page = new Page();   
  39.           
  40.         //方法2:不用进行map传参,用ThreadLocal进行传参,方便没有侵入性  
  41.         PageContext page = PageContext.getContext();  
  42.           
  43.         //请自行验证   
  44.         if(null == pagec)  
  45.           
  46.             page.setCurrentPage(1);  
  47.             page.setPageSize(10);  
  48.           
  49.         else  
  50.             page.setCurrentPage(Integer.parseInt(pagec));  
  51.             page.setPageSize(Integer.parseInt(pageSize));  
  52.             page.setTotalPages(Integer.parseInt(totalPages));  
  53.             page.setTotalRows(Integer.parseInt(totalRows));  
  54.           
  55.         page.setPagination(true);  
  56.   
  57. //      方法1用   
  58. //      Map map = new HashMap();   
  59. //      map.put("page", page);  
  60. //      HandlerResult rs = userService.list(map);  
  61.           
  62.         //方法2用   
  63.         HandlerResult rs = userService.list();  
  64.           
  65.         ModelAndView mv = new ModelAndView("/views/show.jsp");  
  66.         mv.addObject("userList", rs.getResultObj());  
  67.         mv.addObject("page",page);  
  68.         return mv;  
  69.       
  70.   
  71.   
package com.flydreamer.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.flydreamer.logic.UserService;
import com.flydreamer.page.Page;
import com.flydreamer.page.PageContext;
import com.flydreamer.util.web.HandlerResult;

@Controller
@RequestMapping("/user.do")
public class UserController 
	
	@Autowired
	private UserService userService;
	
	@RequestMapping(params = ("method=list"))
	public ModelAndView listAll(HttpServletRequest request,HttpServletResponse response) 
		
		//可以将分页参数获取封装,已达到更好的复用效果。
		//page=2&pageSize=10&totalPages=19&totalRows=188
		String pagec = request.getParameter("page"); 
		String pageSize = request.getParameter("pageSize"); 
		String totalPages = request.getParameter("totalPages"); 
		String totalRows = request.getParameter("totalRows"); 
		
		//方法1:将分页参数直接放到mapper接口函数参数中,也可在对象中定义名字为page的属性,反射一样可以得到
		//后台连接直接获取
		//Page page = new Page();
		
		//方法2:不用进行map传参,用ThreadLocal进行传参,方便没有侵入性
		PageContext page = PageContext.getContext();
		
		//请自行验证
		if(null == pagec)
		
			page.setCurrentPage(1);
			page.setPageSize(10);
		
		else
			page.setCurrentPage(Integer.parseInt(pagec));
			page.setPageSize(Integer.parseInt(pageSize));
			page.setTotalPages(Integer.parseInt(totalPages));
			page.setTotalRows(Integer.parseInt(totalRows));
		
		page.setPagination(true);

//		方法1用
//		Map map = new HashMap();
//		map.put("page", page);
//		HandlerResult rs = userService.list(map);
		
		//方法2用
		HandlerResult rs = userService.list();
		
		ModelAndView mv = new ModelAndView("/views/show.jsp");
		mv.addObject("userList", rs.getResultObj());
		mv.addObject("page",page);
		return mv;
	


简要说明:本文采用两种方式将page对象传入到拦截器中。第一种方式是采用参数传值,不管是用map还是在统一参数对象中名称为page的属性都可以在分页拦截器中得到page的值。第二种方式是用ThreadLocal,对service层没有侵入性。比较方便。


2:Service层代码。没啥可说的上代码

[java] view plain copy print ?
  1. package com.flydreamer.logic;  
  2.   
  3. import java.util.Map;  
  4.   
  5. import org.springframework.beans.factory.annotation.Autowired;  
  6. import org.springframework.stereotype.Service;  
  7.   
  8. import com.flydreamer.orm.mapper.UsersMapper;  
  9. import com.flydreamer.util.web.HandlerResult;  
  10.   
  11. @Service  
  12. public class UserService   
  13.       
  14.     @Autowired  
  15.     private UsersMapper usersMappser;  
  16.   
  17.   
  18.     /** 
  19.      * 统一Service出口,方便管理 
  20.      * @param map 
  21.      * @return 
  22.      */  
  23.     public HandlerResult list(Map map)  
  24.           
  25.         HandlerResult rs = new HandlerResult();  
  26.           
  27.         rs.setResultObj(usersMappser.list(map));  
  28.           
  29.         return rs;  
  30.       
  31.       
  32.     /** 
  33.      * 采用本地线程的方式分页 
  34.      * @return 
  35.      */  
  36.     public HandlerResult list()  
  37.           
  38.         HandlerResult rs = new HandlerResult();  
  39.           
  40.         rs.setResultObj(usersMappser.list2());  
  41.           
  42.         return rs;  
  43.       
  44.       
  45.   
  46.     public UsersMapper getUsersMappser()   
  47.         return usersMappser;  
  48.       
  49.   
  50.     public void setUsersMappser(UsersMapper usersMappser)   
  51.         this.usersMappser = usersMappser;  
  52.       
  53.   
package com.flydreamer.logic;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.flydreamer.orm.mapper.UsersMapper;
import com.flydreamer.util.web.HandlerResult;

@Service
public class UserService 
	
	@Autowired
	private UsersMapper usersMappser;


	/**
	 * 统一Service出口,方便管理
	 * @param map
	 * @return
	 */
	public HandlerResult list(Map map)
		
		HandlerResult rs = new HandlerResult();
		
		rs.setResultObj(usersMappser.list(map));
		
		return rs;
	
	
	/**
	 * 采用本地线程的方式分页
	 * @return
	 */
	public HandlerResult list()
		
		HandlerResult rs = new HandlerResult();
		
		rs.setResultObj(usersMappser.list2());
		
		return rs;
	
	

	public UsersMapper getUsersMappser() 
		return usersMappser;
	

	public void setUsersMappser(UsersMapper usersMappser) 
		this.usersMappser = usersMappser;
	


3:mybatis接口

[java] view plain copy print ?
  1. package com.flydreamer.orm.mapper;  
  2.   
  3. import java.util.List;  
  4. import java.util.Map;  
  5.   
  6. import com.flydreamer.orm.SqlMapper;  
  7.   
  8. public interface UsersMapper extends SqlMapper  
  9.       
  10.     public List list(Map para);  
  11.       
  12.     public List list2();  
  13.   
package com.flydreamer.orm.mapper;

import java.util.List;
import java.util.Map;

import com.flydreamer.orm.SqlMapper;

public interface UsersMapper extends SqlMapper
	
	public List list(Map para);
	
	public List list2();


4:page的拦截器

[java] view plain copy print ?
  1. package com.flydreamer.interceptor;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.PreparedStatement;  
  5. import java.sql.ResultSet;  
  6. import java.sql.SQLException;  
  7. import java.util.List;  
  8. import java.util.Properties;  
  9.   
  10. import org.apache.ibatis.builder.xml.dynamic.ForEachSqlNode;  
  11. import org.apache.ibatis.executor.ErrorContext;  
  12. import org.apache.ibatis.executor.Executor;  
  13. import org.apache.ibatis.executor.ExecutorException;  
  14. import org.apache.ibatis.logging.Log;  
  15. import org.apache.ibatis.logging.LogFactory;  
  16. import org.apache.ibatis.mapping.BoundSql;  
  17. import org.apache.ibatis.mapping.MappedStatement;  
  18. import org.apache.ibatis.mapping.ParameterMapping;  
  19. import org.apache.ibatis.mapping.ParameterMode;  
  20. import org.apache.ibatis.mapping.SqlSource;  
  21. import org.apache.ibatis.mapping.MappedStatement.Builder;  
  22. import org.apache.ibatis.plugin.Interceptor;  
  23. import org.apache.ibatis.plugin.Intercepts;  
  24. import org.apache.ibatis.plugin.Invocation;  
  25. import org.apache.ibatis.plugin.Plugin;  
  26. import org.apache.ibatis.plugin.Signature;  
  27. import org.apache.ibatis.reflection.MetaObject;  
  28. import org.apache.ibatis.reflection.property.PropertyTokenizer;  
  29. import org.apache.ibatis.session.Configuration;  
  30. import org.apache.ibatis.session.ResultHandler;  
  31. import org.apache.ibatis.session.RowBounds;  
  32. import org.apache.ibatis.type.TypeHandler;  
  33. import org.apache.ibatis.type.TypeHandlerRegistry;  
  34.   
  35. import com.flydreamer.page.Dialect;  
  36. import com.flydreamer.page.mysql5Dialect;  
  37. import com.flydreamer.page.OracleDialect;  
  38. import com.flydreamer.page.Page;  
  39. import com.flydreamer.page.PageContext;  
  40. import com.flydreamer.page.ReflectHelper;  
  41.   
  42. //只拦截select部分   
  43. @Intercepts(@Signature(type=Executor.class,method="query",args= MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class ))  
  44. public class PaginationInterceptor implements Interceptor  
  45.       
  46.     private final static Log log = LogFactory.getLog(PaginationInterceptor.class);     
  47.       
  48.     Dialect dialect = new MySql5Dialect();  
  49.        
  50.     public Object intercept(Invocation invocation) throws Throwable   
  51.           
  52.         MappedStatement mappedStatement=(MappedStatement)invocation.getArgs()[0];         
  53.         Object parameter = invocation.getArgs()[1];   
  54.         BoundSql boundSql = mappedStatement.getBoundSql(parameter);   
  55.         String originalSql = boundSql.getSql().trim();     
  56.         RowBounds rowBounds = (RowBounds)invocation.getArgs()[2];  
  57.   
  58.         Object parameterObject = boundSql.getParameterObject();  
  59.         if(boundSql==null || boundSql.getSql()==null || "".equals(boundSql.getSql()))  
  60.             return null;  
  61.         //分页参数--上下文传参   
  62.         Page page = null;  
  63.         PageContext context=PageContext.getContext();  
  64.           
  65.         //map传参每次都将currentPage重置,先判读map再判断context  
  66.         if(parameterObject!=null)  
  67.             page = (Page)ReflectHelper.isPage(parameterObject,"page");  
  68.           
  69.         //分页参数--context参数里的Page传参  
  70.         if(page==null && context.isPagination()==true)  
  71.           
  72.             page = context;  
  73.           
  74.           
  75.         //后面用到了context的东东   
  76.         if(page!=null && page.isPagination()==true)               
  77.           
  78.           int totpage=page.getTotalRows();    
  79.           //得到总记录数   
  80.           if (totpage==0)  
  81.               
  82.                 StringBuffer countSql  = new StringBuffer(originalSql.length()+100 );  
  83.                 countSql.append("select count(1) from (").append(originalSql).append(") t");  
  84.                      Connection connection=mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection()  ;            
  85.                  PreparedStatement countStmt = connection.prepareStatement(countSql.toString());    
  86.                  BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(),countSql.toString(),boundSql.getParameterMappings(),parameterObject);    
  87.                  setParameters(countStmt,mappedStatement,countBS,parameterObject);    
  88.                  ResultSet rs = countStmt.executeQuery();    
  89.                  if (rs.next())     
  90.                      totpage = rs.getInt(1);    
  91.                      
  92.                  rs.close();    
  93.                  countStmt.close();    
  94.                  connection.close();  
  95.               
  96.             
  97.             //分页计算   
  98.             page.init(totpage,page.getPageSize(),page.getCurrentPage());  
  99.             
  100.             if(rowBounds == null || rowBounds == RowBounds.DEFAULT)  
  101.                 rowBounds= new RowBounds(page.getPageSize()*(page.getCurrentPage()-1),page.getPageSize());  
  102.                   
  103.                  
  104.   
  105.             //分页查询 本地化对象 修改数据库注意修改实现  
  106.             String pagesql=dialect.getLimitString(originalSql, rowBounds.getOffset(), rowBounds.getLimit());  
  107.             invocation.getArgs()[2] = new RowBounds(RowBounds.NO_ROW_OFFSET, RowBounds.NO_ROW_LIMIT);     
  108.             BoundSql newBoundSql = new BoundSql(mappedStatement.getConfiguration(), pagesql,boundSql.getParameterMappings(),boundSql.getParameterObject());     
  109.             MappedStatement newMs = copyFromMappedStatement(mappedStatement,new BoundSqlSqlSource(newBoundSql));    
  110.              
  111.             invocation.getArgs()[0]= newMs;    
  112.           
  113.               
  114.               
  115.            return invocation.proceed();  
  116.           
  117.       
  118.     public static class BoundSqlSqlSource implements SqlSource     
  119.         BoundSql boundSql;    
  120.     
  121.         public BoundSqlSqlSource(BoundSql boundSql)     
  122.             this.boundSql = boundSql;    
  123.             
  124.     
  125.         public BoundSql getBoundSql(Object parameterObject)     
  126.             return boundSql;    
  127.             
  128.         
  129.     public Object plugin(Object arg0)   
  130.          return Plugin.wrap(arg0, this);  
  131.       
  132.     public void setProperties(Properties arg0)   
  133.               
  134.       
  135.       
  136.     /**  
  137.      * 对SQL参数(?)设值,参考org.apache.ibatis.executor.parameter.DefaultParameterHandler  
  138.      * @param ps  
  139.      * @param mappedStatement  
  140.      * @param boundSql  
  141.      * @param parameterObject  
  142.      * @throws SQLException  
  143.      */    
  144.     private void setParameters(PreparedStatement ps,MappedStatement mappedStatement,BoundSql boundSql,Object parameterObject) throws SQLException     
  145.         ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());    
  146.         List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();    
  147.         if (parameterMappings != null)     
  148.             Configuration configuration = mappedStatement.getConfiguration();    
  149.             TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();    
  150.             MetaObject metaObject = parameterObject == null ? null: configuration.newMetaObject(parameterObject);    
  151.             for (int i = 0; i < parameterMappings.size(); i++)     
  152.                 ParameterMapping parameterMapping = parameterMappings.get(i);    
  153.                 if (parameterMapping.getMode() != ParameterMode.OUT)     
  154.                     Object value;    
  155.                     String propertyName = parameterMapping.getProperty();    
  156.                     PropertyTokenizer prop = new PropertyTokenizer(propertyName);    
  157.                     if (parameterObject == null)     
  158.                         value = null;    
  159.                      else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))     
  160.                         value = parameterObject;    
  161.                      else if (boundSql.hasAdditionalParameter(propertyName))     
  162.                         value = boundSql.getAdditionalParameter(propertyName);    
  163.                      else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX)&& boundSql.hasAdditionalParameter(prop.getName()))     
  164.                         value = boundSql.getAdditionalParameter(prop.getName());    
  165.                         if (value != null)     
  166.                             value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));    
  167.                             
  168.                      else     
  169.                         value = metaObject == null ? null : metaObject.getValue(propertyName);    
  170.                         
  171.                     TypeHandler typeHandler = parameterMapping.getTypeHandler();    
  172.                     if (typeHandler == null)     
  173.                         throw new ExecutorException("There was no TypeHandler found for parameter "+ propertyName + " of statement "+ mappedStatement.getId());    
  174.                         
  175.                     typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType());    
  176.                     
  177.                 
  178.             
  179.         
  180.       
  181.     private MappedStatement copyFromMappedStatement(MappedStatement ms,     
  182.              SqlSource newSqlSource)      
  183.             Builder builder = new MappedStatement.Builder(ms.getConfiguration(),     
  184.             ms.getId(), newSqlSource, ms.getSqlCommandType());     
  185.             builder.resource(ms.getResource());     
  186.             builder.fetchSize(ms.getFetchSize());     
  187.             builder.statementType(ms.getStatementType());     
  188.             builder.keyGenerator(ms.getKeyGenerator());     
  189.             builder.keyProperty(ms.getKeyProperty());     
  190.             builder.timeout(ms.getTimeout());     
  191.              builder.parameterMap(ms.getParameterMap());     
  192.             builder.resultMaps(ms.getResultMaps());     
  193.             builder.cache(ms.getCache());     
  194.             MappedStatement newMs = builder.build();     
  195.             return newMs;     
  196.                  
  197.            
  198.   
  199.   
package com.flydreamer.interceptor;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;

import org.apache.ibatis.builder.xml.dynamic.ForEachSqlNode;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.ExecutorException;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.mapping.MappedStatement.Builder;
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.MetaObject;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;

import com.flydreamer.page.Dialect;
import com.flydreamer.page.MySql5Dialect;
import com.flydreamer.page.OracleDialect;
import com.flydreamer.page.Page;
import com.flydreamer.page.PageContext;
import com.flydreamer.page.ReflectHelper;

//只拦截select部分
@Intercepts(@Signature(type=Executor.class,method="query",args= MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class ))
public class PaginationInterceptor implements Interceptor
	
	private final static Log log = LogFactory.getLog(PaginationInterceptor.class);   
	
	Dialect dialect = new MySql5Dialect();
	 
	public Object intercept(Invocation invocation) throws Throwable 
		
		MappedStatement mappedStatement=(MappedStatement)invocation.getArgs()[0];		
		Object parameter = invocation.getArgs()[1]; 
		BoundSql boundSql = mappedStatement.getBoundSql(parameter); 
		String originalSql = boundSql.getSql().trim();   
		RowBounds rowBounds = (RowBounds)invocation.getArgs()[2];

		Object parameterObject = boundSql.getParameterObject();
		if(boundSql==null || boundSql.getSql()==null || "".equals(boundSql.getSql()))
			return null;
		//分页参数--上下文传参
		Page page = null;
		PageContext context=PageContext.getContext();
		
		//map传参每次都将currentPage重置,先判读map再判断context
		if(parameterObject!=null)
			page = (Page)ReflectHelper.isPage(parameterObject,"page");
		
		//分页参数--context参数里的Page传参
		if(page==null && context.isPagination()==true)
		
			page = context;
		
		
		//后面用到了context的东东
		if(page!=null && page.isPagination()==true) 			
		
		  int totpage=page.getTotalRows();	
		  //得到总记录数
		  if (totpage==0)
			
				StringBuffer countSql  = new StringBuffer(originalSql.length()+100 );
				countSql.append("select count(1) from (").append(originalSql).append(") t");
					 Connection connection=mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection()  ;          
                 PreparedStatement countStmt = connection.prepareStatement(countSql.toString());  
                 BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(),countSql.toString(),boundSql.getParameterMappings(),parameterObject);  
                 setParameters(countStmt,mappedStatement,countBS,parameterObject);  
                 ResultSet rs = countStmt.executeQuery();  
                 if (rs.next())   
                	 totpage = rs.getInt(1);  
                   
                 rs.close();  
                 countStmt.close();  
                 connection.close();
			
		  
		    //分页计算
	        page.init(totpage,page.getPageSize(),page.getCurrentPage());
		  
			if(rowBounds == null || rowBounds == RowBounds.DEFAULT)
				rowBounds= new RowBounds(page.getPageSize()*(page.getCurrentPage()-1),page.getPageSize());
				
				

			//分页查询 本地化对象 修改数据库注意修改实现
		    String pagesql=dialect.getLimitString(originalSql, rowBounds.getOffset(), rowBounds.getLimit());
		    invocation.getArgs()[2] = new RowBounds(RowBounds.NO_ROW_OFFSET, RowBounds.NO_ROW_LIMIT);   
		    BoundSql newBoundSql = new BoundSql(mappedStatement.getConfiguration(), pagesql,boundSql.getParameterMappings(),boundSql.getParameterObject());   
		    MappedStatement newMs = copyFromMappedStatement(mappedStatement,new BoundSqlSqlSource(newBoundSql));  
		   
		    invocation.getArgs()[0]= newMs;  
		
			
			
		   return invocation.proceed();
		
	
	public static class BoundSqlSqlSource implements SqlSource   
        BoundSql boundSql;  
  
        public BoundSqlSqlSource(BoundSql boundSql)   
            this.boundSql = boundSql;  
          
  
        public BoundSql getBoundSql(Object parameterObject)   
            return boundSql;  
          
      
	public Object plugin(Object arg0) 
		 return Plugin.wrap(arg0, this);
	
	public void setProperties(Properties arg0) 
	        
	
    
    /** 
     * 对SQL参数(?)设值,参考org.apache.ibatis.executor.parameter.DefaultParameterHandler 
     * @param ps 
     * @param mappedStatement 
     * @param boundSql 
     * @param parameterObject 
     * @throws SQLException 
     */  
    private void setParameters(PreparedStatement ps,MappedStatement mappedStatement,BoundSql boundSql,Object parameterObject) throws SQLException   
        ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());  
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();  
        if (parameterMappings != null)   
            Configuration configuration = mappedStatement.getConfiguration();  
            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();  
            MetaObject metaObject = parameterObject == null ? null: configuration.newMetaObject(parameterObject);  
            for (int i = 0; i < parameterMappings.size(); i++)   
                ParameterMapping parameterMapping = parameterMappings.get(i);  
                if (parameterMapping.getMode() != ParameterMode.OUT)   
                    Object value;  
                    String propertyName = parameterMapping.getProperty();  
                    PropertyTokenizer prop = new PropertyTokenizer(propertyName);  
                    if (parameterObject == null)   
                        value = null;  
                     else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))   
                        value = parameterObject;  
                     else if (boundSql.hasAdditionalParameter(propertyName))   
                        value = boundSql.getAdditionalParameter(propertyName);  
                     else if (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);  
                      
                    TypeHandler typeHandler = parameterMapping.getTypeHandler();  
                    if (typeHandler == null)   
                        throw new ExecutorException("There was no TypeHandler found for parameter "+ propertyName + " of statement "+ mappedStatement.getId());  
                      
                    typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType());  
                  
              
          
      
    
    private MappedStatement copyFromMappedStatement(MappedStatement ms,   
    		 SqlSource newSqlSource)    
    		Builder builder = new MappedStatement.Builder(ms.getConfiguration(),   
    		ms.getId(), newSqlSource, ms.getSqlCommandType());   
    		builder.resource(ms.getResource());   
    		builder.fetchSize(ms.getFetchSize());   
    		builder.statementType(ms.getStatementType());   
    		builder.keyGenerator(ms.getKeyGenerator());   
    		builder.keyProperty(ms.getKeyProperty());   
    		builder.timeout(ms.getTimeout());   
    		 builder.parameterMap(ms.getParameterMap());   
    		builder.resultMaps(ms.getResultMaps());   
    		builder.cache(ms.getCache());   
    		MappedStatement newMs = builder.build();   
    		return newMs;   
    		   
    	 

简要说明:刚刚忘记了,有一些查询操作是不需要分页的。可以自行修改拦截器中代码部分,加个判断啥的。

5:spring 配置

[html] view plain copy print ?
  1. <bean id="paginationInterceptor" class="com.flydreamer.interceptor.PaginationInterceptor"></bean>    
<bean id="paginationInterceptor" class="com.flydreamer.interceptor.PaginationInterceptor"></bean>  

[html] view plain copy print ?
  1. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">    
  2.         <property name="dataSource" ref="dataSource" />    
  3.           
  4.         <property name="plugins">  
  5.             <ref bean="paginationInterceptor"/>  
  6.         </property>  
  7.     </bean>    
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
	    <property name="dataSource" ref="dataSource" />  
	    
	    <property name="plugins">
	    	<ref bean="paginationInterceptor"/>
	    </property>
    </bean>  

大致就是这样了。完整的可运行项目已放到这里。最近CSDN没有分了,收1分,各位童鞋见谅了~

以上是关于spring+mybatis 物理分页的主要内容,如果未能解决你的问题,请参考以下文章

关于mybatis物理分页的问题,求大神帮忙看看

Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)(转)

Mybatis 物理分页

Mybatis分页对比MybatisPlus分页

MyBatis 物理分页foreach 参数失效

Mybatis是如何进行分页的?