MyBatis3-实现MyBatis分页
此文章中的例子是沿用上一篇文章http://www.cnblogs.com/EasonJim/p/7055499.html的 Spring MVC 集成的例子改装的。
MyBatis 分页有以下方式实现:
一、内存分页,使用 RowBounds 类,但这种方式不推荐,基本不用,所以此方式集成省略。
二、自定义实现,代码量比较少,简单,比较灵活。以下为具体的集成步骤:
1、在 User.xml 中加入 select 节点,并组装分页 SQL
<select id="getUserArticlesByLimit" parameterType="int" resultMap="resultUserArticleList"> select user.id,user.userName,user.userAddress,article.id as aid,article.title,article.content from user,article where user.id=article.userid and user.id=#{arg0} limit #{arg1},#{arg2} </select>
注意:上面的写法中 select 节点的 parameterType 属性为 int 类型,而此时是由于当前业务的 SQL 语句就是全部都是 int 型的,当对于多类型时,这种属性就不能这么设置了。具体的在多参数中会进行讲解。
2、在 IUserOperation.java 中加入 Mapping 对应的方法
public List<Article> getUserArticlesByLimit(int id,int start,int limit);
3、修改 UserController.java 中获取数据的方法,改成分页方法,并传入指定参数
package com.jsoft.testmybatis.controller;import java.util.List;
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.jsoft.testmybatis.inter.IUserOperation;
import com.jsoft.testmybatis.models.Article;@Controller
@RequestMapping("/article")
public class UserController {
@Autowired
IUserOperation userMapper;@RequestMapping(</span>"/list"<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> ModelAndView listall(HttpServletRequest request,HttpServletResponse response){ List</span><Article> articles=userMapper.<span style="color: rgba(255, 0, 0, 1)"><strong>getUserArticlesByLimit(1,0,2</strong></span><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><strong>)</strong></span>; ModelAndView mav</span>=<span style="color: rgba(0, 0, 255, 1)">new</span> ModelAndView("/article/list"<span style="color: rgba(0, 0, 0, 1)">); mav.addObject(</span>"articles"<span style="color: rgba(0, 0, 0, 1)">,articles); </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> mav; }
}
意思是获取用户 1 的数据,从第 0 行开始的 2 条数据。
4、运行测试
mvn tomcat7:run
三、通过自定义插件的形式实现分页,也是最好的,也叫做分页拦截器。实现步骤如下:
插件支持 MySQL 和 Oracle 两种数据库,通过方法名关键字 ListPage 去匹配,有才进行分页处理,并且不用在 Mapping 中写分页代码。
1、在 User.xml 中添加查询语句
<!-- 插件式分页查询测试 --> <select id="selectArticleListPage" resultMap="resultUserArticleList"> select user.id,user.userName,user.userAddress,article.id as aid,article.title,article.content from user,article where user.id=article.userid and user.id=#{userid} </select>
2、在 IUserOperation.java 中添加接口
public List<Article> selectArticleListPage( @Param("page") PageInfo page, @Param("userid") int userid);
3、以下是插件实现的三个类
PageInfo.java:
package com.jsoft.testmybatis.util;import java.io.Serializable;
public class PageInfo implements Serializable {
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">long</span> serialVersionUID = 587754556498974978L<span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> pagesize ,每一页显示多少</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> showCount = 3<span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 总页数</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> totalPage; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 总记录数</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> totalResult; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 当前页数</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> currentPage; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 当前显示到的ID, 在mysql limit 中就是第一个参数.</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> currentResult; </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String sortField; </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String order; </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getShowCount() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> showCount; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setShowCount(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> showCount) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.showCount =<span style="color: rgba(0, 0, 0, 1)"> showCount; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getTotalPage() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> totalPage; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setTotalPage(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> totalPage) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.totalPage =<span style="color: rgba(0, 0, 0, 1)"> totalPage; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getTotalResult() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> totalResult; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setTotalResult(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> totalResult) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.totalResult =<span style="color: rgba(0, 0, 0, 1)"> totalResult; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getCurrentPage() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> currentPage; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setCurrentPage(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> currentPage) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.currentPage =<span style="color: rgba(0, 0, 0, 1)"> currentPage; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getCurrentResult() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> currentResult; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setCurrentResult(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> currentResult) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.currentResult =<span style="color: rgba(0, 0, 0, 1)"> currentResult; } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getSortField() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sortField; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setSortField(String sortField) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.sortField =<span style="color: rgba(0, 0, 0, 1)"> sortField; } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getOrder() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> order; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setOrder(String order) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.order =<span style="color: rgba(0, 0, 0, 1)"> order; }
}
ReflectHelper.java:
package com.jsoft.testmybatis.util;import java.lang.reflect.Field;
public class ReflectHelper {
public static Field getFieldByFieldName(Object obj, String fieldName) {
for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
try {
return superClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
}
}
return null;
}</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * Obj fieldName的获取属性值. * * </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> obj * </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> fieldName * </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> * </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> SecurityException * </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> NoSuchFieldException * </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> IllegalArgumentException * </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> IllegalAccessException </span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> Object getValueByFieldName(Object obj, String fieldName) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field field </span>=<span style="color: rgba(0, 0, 0, 1)"> getFieldByFieldName(obj, fieldName); Object value </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (field != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (field.isAccessible()) { value </span>=<span style="color: rgba(0, 0, 0, 1)"> field.get(obj); } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { field.setAccessible(</span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">); value </span>=<span style="color: rgba(0, 0, 0, 1)"> field.get(obj); field.setAccessible(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">); } } </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> value; } </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * obj fieldName设置的属性值. * * </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> obj * </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> fieldName * </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> value * </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> SecurityException * </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> NoSuchFieldException * </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> IllegalArgumentException * </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> IllegalAccessException </span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setValueByFieldName(Object obj, String fieldName, Object value) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field field </span>=<span style="color: rgba(0, 0, 0, 1)"> obj.getClass().getDeclaredField(fieldName); </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (field.isAccessible()) { field.set(obj, value); } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { field.setAccessible(</span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">); field.set(obj, value); field.setAccessible(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">); } }
}
PagePlugin.java:
package com.jsoft.testmybatis.util;import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Properties;import javax.xml.bind.PropertyException;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.ExecutorException;
import org.apache.ibatis.executor.statement.BaseStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
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.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.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class })})
public class PagePlugin implements Interceptor {</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String dialect = ""<span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String pageSqlId = ""<span style="color: rgba(0, 0, 0, 1)">; @SuppressWarnings(</span>"unchecked"<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">public</span> Object intercept(Invocation ivk) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Throwable { </span><span style="color: rgba(0, 0, 255, 1)">if</span> (ivk.getTarget() <span style="color: rgba(0, 0, 255, 1)">instanceof</span><span style="color: rgba(0, 0, 0, 1)"> RoutingStatementHandler) { RoutingStatementHandler statementHandler </span>=<span style="color: rgba(0, 0, 0, 1)"> (RoutingStatementHandler) ivk.getTarget(); BaseStatementHandler delegate </span>= (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate"<span style="color: rgba(0, 0, 0, 1)">); MappedStatement mappedStatement </span>= (MappedStatement) ReflectHelper.getValueByFieldName(delegate, "mappedStatement"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (mappedStatement.getId().matches(pageSqlId)) { BoundSql boundSql </span>=<span style="color: rgba(0, 0, 0, 1)"> delegate.getBoundSql(); Object parameterObject </span>=<span style="color: rgba(0, 0, 0, 1)"> boundSql.getParameterObject(); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (parameterObject == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { </span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> NullPointerException("parameterObject error"<span style="color: rgba(0, 0, 0, 1)">); } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { Connection connection </span>= (Connection) ivk.getArgs()[0<span style="color: rgba(0, 0, 0, 1)">]; String sql </span>=<span style="color: rgba(0, 0, 0, 1)"> boundSql.getSql(); String countSql </span>= "select count(0) from (" + sql + ") myCount"<span style="color: rgba(0, 0, 0, 1)">; System.out.println(</span>"总数sql 语句:" +<span style="color: rgba(0, 0, 0, 1)"> countSql); PreparedStatement countStmt </span>=<span style="color: rgba(0, 0, 0, 1)"> connection.prepareStatement(countSql); BoundSql countBS </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), parameterObject); setParameters(countStmt, mappedStatement, countBS, parameterObject); ResultSet rs </span>=<span style="color: rgba(0, 0, 0, 1)"> countStmt.executeQuery(); </span><span style="color: rgba(0, 0, 255, 1)">int</span> count = 0<span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (rs.next()) { count </span>= rs.getInt(1<span style="color: rgba(0, 0, 0, 1)">); } rs.close(); countStmt.close(); PageInfo page </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (parameterObject <span style="color: rgba(0, 0, 255, 1)">instanceof</span><span style="color: rgba(0, 0, 0, 1)"> PageInfo) { page </span>=<span style="color: rgba(0, 0, 0, 1)"> (PageInfo) parameterObject; page.setTotalResult(count); } </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (parameterObject <span style="color: rgba(0, 0, 255, 1)">instanceof</span><span style="color: rgba(0, 0, 0, 1)"> Map) { Map</span><String, Object> map = (Map<String, Object><span style="color: rgba(0, 0, 0, 1)">) parameterObject; page </span>= (PageInfo) map.get("page"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (page == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) page </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> PageInfo(); page.setTotalResult(count); } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { Field pageField </span>= ReflectHelper.getFieldByFieldName(parameterObject, "page"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (pageField != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { page </span>= (PageInfo) ReflectHelper.getValueByFieldName(parameterObject, "page"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (page == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) page </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> PageInfo(); page.setTotalResult(count); ReflectHelper.setValueByFieldName(parameterObject, </span>"page"<span style="color: rgba(0, 0, 0, 1)">, page); } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> NoSuchFieldException(parameterObject.getClass().getName()); } } String pageSql </span>=<span style="color: rgba(0, 0, 0, 1)"> generatePageSql(sql, page); System.out.println(</span>"page sql:" +<span style="color: rgba(0, 0, 0, 1)"> pageSql); ReflectHelper.setValueByFieldName(boundSql, </span>"sql"<span style="color: rgba(0, 0, 0, 1)">, pageSql); } } } </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ivk.proceed(); } </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> SQLException { ErrorContext.instance().activity(</span>"setting parameters"<span style="color: rgba(0, 0, 0, 1)">).object(mappedStatement.getParameterMap().getId()); List</span><ParameterMapping> parameterMappings =<span style="color: rgba(0, 0, 0, 1)"> boundSql.getParameterMappings(); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (parameterMappings != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { Configuration configuration </span>=<span style="color: rgba(0, 0, 0, 1)"> mappedStatement.getConfiguration(); TypeHandlerRegistry typeHandlerRegistry </span>=<span style="color: rgba(0, 0, 0, 1)"> configuration.getTypeHandlerRegistry(); MetaObject metaObject </span>= parameterObject == <span style="color: rgba(0, 0, 255, 1)">null</span> ? <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)"> : configuration.newMetaObject(parameterObject); </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < parameterMappings.size(); i++<span style="color: rgba(0, 0, 0, 1)">) { ParameterMapping parameterMapping </span>=<span style="color: rgba(0, 0, 0, 1)"> parameterMappings.get(i); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (parameterMapping.getMode() !=<span style="color: rgba(0, 0, 0, 1)"> ParameterMode.OUT) { Object value; String propertyName </span>=<span style="color: rgba(0, 0, 0, 1)"> parameterMapping.getProperty(); PropertyTokenizer prop </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> PropertyTokenizer(propertyName); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (parameterObject == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { value </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { value </span>=<span style="color: rgba(0, 0, 0, 1)"> parameterObject; } </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (boundSql.hasAdditionalParameter(propertyName)) { value </span>=<span style="color: rgba(0, 0, 0, 1)"> boundSql.getAdditionalParameter(propertyName); } </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) &&<span style="color: rgba(0, 0, 0, 1)"> boundSql.hasAdditionalParameter(prop.getName())) { value </span>=<span style="color: rgba(0, 0, 0, 1)"> boundSql.getAdditionalParameter(prop.getName()); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (value != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { value </span>=<span style="color: rgba(0, 0, 0, 1)"> configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length())); } } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { value </span>= metaObject == <span style="color: rgba(0, 0, 255, 1)">null</span> ? <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)"> : metaObject.getValue(propertyName); } TypeHandler typeHandler </span>=<span style="color: rgba(0, 0, 0, 1)"> parameterMapping.getTypeHandler(); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (typeHandler == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { </span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> ExecutorException("There was no TypeHandler found for parameter " + propertyName + " of statement " +<span style="color: rgba(0, 0, 0, 1)"> mappedStatement.getId()); } typeHandler.setParameter(ps, i </span>+ 1<span style="color: rgba(0, 0, 0, 1)">, value, parameterMapping.getJdbcType()); } } } } </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String generatePageSql(String sql, PageInfo page) { </span><span style="color: rgba(0, 0, 255, 1)">if</span> (page != <span style="color: rgba(0, 0, 255, 1)">null</span> && (dialect != <span style="color: rgba(0, 0, 255, 1)">null</span> || !dialect.equals(""<span style="color: rgba(0, 0, 0, 1)">))) { StringBuffer pageSql </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StringBuffer(); </span><span style="color: rgba(0, 0, 255, 1)">if</span> ("mysql"<span style="color: rgba(0, 0, 0, 1)">.equals(dialect)) { pageSql.append(sql); pageSql.append(</span>" limit " + page.getCurrentResult() + "," +<span style="color: rgba(0, 0, 0, 1)"> page.getShowCount()); } </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> ("oracle"<span style="color: rgba(0, 0, 0, 1)">.equals(dialect)) { pageSql.append(</span>"select * from (select tmp_tb.*,ROWNUM row_id from ("<span style="color: rgba(0, 0, 0, 1)">); pageSql.append(sql); pageSql.append(</span>") tmp_tb where ROWNUM<="<span style="color: rgba(0, 0, 0, 1)">); pageSql.append(page.getCurrentResult() </span>+<span style="color: rgba(0, 0, 0, 1)"> page.getShowCount()); pageSql.append(</span>") where row_id>"<span style="color: rgba(0, 0, 0, 1)">); pageSql.append(page.getCurrentResult()); } </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> pageSql.toString(); } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sql; } } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Object plugin(Object arg0) { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO Auto-generated method stub</span> <span style="color: rgba(0, 0, 255, 1)">return</span> Plugin.wrap(arg0, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">); } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setProperties(Properties p) { dialect </span>= p.getProperty("dialect"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (dialect == <span style="color: rgba(0, 0, 255, 1)">null</span> || dialect.equals(""<span style="color: rgba(0, 0, 0, 1)">)) { </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> PropertyException("dialect property is not found!"<span style="color: rgba(0, 0, 0, 1)">); } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (PropertyException e) { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO Auto-generated catch block</span>
e.printStackTrace();
}
}
pageSqlId = p.getProperty("pageSqlId");
if (dialect == null || dialect.equals("")) {
try {
throw new PropertyException("pageSqlId property is not found!");
} catch (PropertyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}}
4、在 Configuration.xml 中配置插件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <typeAlias alias="PageInfo" type="com.jsoft.testmybatis.util.PageInfo" /> </typeAliases> <plugins> <plugin interceptor="com.jsoft.testmybatis.util.PagePlugin"> <property name="dialect" value="mysql" /> <property name="pageSqlId" value=".*ListPage.*" /> </plugin> </plugins></configuration>
注意:这个插件定义了一个规则,也就是在 mapper 中 SQL 语句的 id 必须包含 ListPage 才能被拦截。否则将不会分页处理。
5、在 UserController.java 中添加测试的 Controller
@RequestMapping("/pagelist") public ModelAndView pageList(HttpServletRequest request, HttpServletResponse response) { int currentPage = request.getParameter("page") == null ? 1 : Integer.parseInt(request.getParameter("page")); int pageSize = 3; if (currentPage <= 0) { currentPage = 1; } int currentResult = (currentPage - 1) * pageSize;System.out.println(request.getRequestURI()); System.out.println(request.getQueryString()); PageInfo page </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> PageInfo(); page.setShowCount(pageSize); page.setCurrentResult(currentResult); List</span><Article> articles = userMapper.selectArticleListPage(page, 1<span style="color: rgba(0, 0, 0, 1)">); System.out.println(page); </span><span style="color: rgba(0, 0, 255, 1)">int</span> totalCount =<span style="color: rgba(0, 0, 0, 1)"> page.getTotalResult(); </span><span style="color: rgba(0, 0, 255, 1)">int</span> lastPage = 0<span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (totalCount % pageSize == 0<span style="color: rgba(0, 0, 0, 1)">) { lastPage </span>= totalCount %<span style="color: rgba(0, 0, 0, 1)"> pageSize; } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { lastPage </span>= 1 + totalCount /<span style="color: rgba(0, 0, 0, 1)"> pageSize; } </span><span style="color: rgba(0, 0, 255, 1)">if</span> (currentPage >=<span style="color: rgba(0, 0, 0, 1)"> lastPage) { currentPage </span>=<span style="color: rgba(0, 0, 0, 1)"> lastPage; } String pageStr </span>= ""<span style="color: rgba(0, 0, 0, 1)">; pageStr </span>= String.format("<a href=\"%s\">上一页</a> <a href=\"%s\">下一页</a>", request.getRequestURI() + "?page=" + (currentPage - 1), request.getRequestURI() + "?page=" + (currentPage + 1<span style="color: rgba(0, 0, 0, 1)">)); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 制定视图,也就是list.jsp</span> ModelAndView mav = <span style="color: rgba(0, 0, 255, 1)">new</span> ModelAndView("/article/pagelist"<span style="color: rgba(0, 0, 0, 1)">); mav.addObject(</span>"articles"<span style="color: rgba(0, 0, 0, 1)">, articles); mav.addObject(</span>"pageStr"<span style="color: rgba(0, 0, 0, 1)">, pageStr); </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> mav; }</span></pre>
6、页面文件 pagelist.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <c:forEach items="${articles}" var="item"> ${item.id}--${item.title}--${item.content}<br /> </c:forEach> <div style="padding:20px;">${pageStr}</div> </body> </html>
7、测试结果:
测试工程:https://github.com/easonjim/5_java_example/tree/master/mybatis/test7
参考: