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>&lt;Article&gt; 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>&lt;String, Object&gt; map = (Map&lt;String, Object&gt;<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>&lt;ParameterMapping&gt; 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 &lt; 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) &amp;&amp;<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> &amp;&amp; (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&lt;="<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&gt;"<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>&lt;Article&gt; 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 &gt;=<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("&lt;a href=\"%s\"&gt;上一页&lt;/a&gt;    &lt;a href=\"%s\"&gt;下一页&lt;/a&gt;", 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

 

参考:

http://www.yihaomen.com/article/java/326.htm