PageInterceptor.java

@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PageInterceptor implements Interceptor {
private static final Logger logger = Logger
.getLogger(PageInterceptor.class);
private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
private static String defaultPageSqlId = ".*Page$"; // 需要拦截的ID(正则匹配)
private static String pageSqlId = ""; // 需要拦截的ID(正则匹配) @Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation
.getTarget();
MetaObject metaStatementHandler = MetaObject.forObject(
statementHandler, DEFAULT_OBJECT_FACTORY,
DEFAULT_OBJECT_WRAPPER_FACTORY);
// 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环可以分离出最原始的的目标类)
while (metaStatementHandler.hasGetter("h")) {
Object object = metaStatementHandler.getValue("h");
metaStatementHandler = MetaObject.forObject(object,
DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
}
// 分离最后一个代理对象的目标类
while (metaStatementHandler.hasGetter("target")) {
Object object = metaStatementHandler.getValue("target");
metaStatementHandler = MetaObject.forObject(object,
DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
}
Configuration configuration = (Configuration) metaStatementHandler
.getValue("delegate.configuration");
Properties properties = configuration.getVariables();
if (null != properties
&& StringUtils.isNotBlank(properties.getProperty("pageSqlId"))) {
pageSqlId = properties.getProperty("pageSqlId");
} else {
pageSqlId = defaultPageSqlId;
} MappedStatement mappedStatement = (MappedStatement) metaStatementHandler
.getValue("delegate.mappedStatement");
// 只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的MappedStatement的sql
if (mappedStatement.getId().matches(pageSqlId)) {
BoundSql boundSql = (BoundSql) metaStatementHandler
.getValue("delegate.boundSql");
Object parameterObject = boundSql.getParameterObject(); if (parameterObject == null) {
throw new NullPointerException("parameterObject is null!");
}
Map<String, Object> paramMap = (Map) parameterObject; PageParameter page = (PageParameter) paramMap.get("0");
String sql = boundSql.getSql();
// 重写sql
String pageSql = buildPageSqlForMysql(sql, page);
metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
// 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
metaStatementHandler.setValue("delegate.rowBounds.offset",
RowBounds.NO_ROW_OFFSET);
metaStatementHandler.setValue("delegate.rowBounds.limit",
RowBounds.NO_ROW_LIMIT);
Connection connection = (Connection) invocation.getArgs()[0];
// 重设分页参数里的总页数等
setPageParameter(sql, connection, mappedStatement, boundSql, page);
}
// 将执行权交给下一个拦截器
return invocation.proceed();
} @Override
public Object plugin(Object target) {
// 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的次数
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
} @Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub } /**
* mysql的分页语句
*
* @param sql
* @param page
* @return String
*/
public String buildPageSqlForMysql(String sql, PageParameter page) {
StringBuilder pageSql = new StringBuilder(100);
String beginrow = String.valueOf((page.getCurrentPage() - 1)
* page.getPageSize());
pageSql.append(sql);
pageSql.append(" limit " + beginrow + "," + page.getPageSize());
return pageSql.toString();
} private void setPageParameter(String sql, Connection connection,
MappedStatement mappedStatement, BoundSql boundSql,
PageParameter page) {
// 记录总记录数
String countSql = "select count(0) from (" + sql + ") as total";
PreparedStatement countStmt = null;
ResultSet rs = null;
try {
countStmt = connection.prepareStatement(countSql);
BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(),
countSql, boundSql.getParameterMappings(),
boundSql.getParameterObject());
setParameters(countStmt, mappedStatement, countBS,
boundSql.getParameterObject());
rs = countStmt.executeQuery();
int totalCount = 0;
if (rs.next()) {
totalCount = rs.getInt(1);
}
page.setTotalCount(totalCount);
int totalPage = totalCount / page.getPageSize()
+ ((totalCount % page.getPageSize() == 0) ? 0 : 1);
page.setTotalPage(totalPage); } catch (SQLException e) {
logger.error("Ignore this exception", e);
} finally {
try {
rs.close();
} catch (SQLException e) {
logger.error("Ignore this exception", e);
}
try {
countStmt.close();
} catch (SQLException e) {
logger.error("Ignore this exception", e);
}
} } private void setParameters(PreparedStatement ps,
MappedStatement mappedStatement, BoundSql boundSql,
Object parameterObject) throws SQLException {
ParameterHandler parameterHandler = new DefaultParameterHandler(
mappedStatement, parameterObject, boundSql);
parameterHandler.setParameters(ps);
}
}

PageParameter.java

public class PageParameter {
public static final int DEFAULT_PAGE_SIZE = 10; private int pageSize;
private int currentPage;
private int prePage;
private int nextPage;
private int totalPage;
private int totalCount; public PageParameter() {
this.currentPage = 1;
this.pageSize = DEFAULT_PAGE_SIZE;
} /**
*
* @param currentPage
* @param pageSize
*/
public PageParameter(int currentPage, int pageSize) {
this.currentPage = currentPage;
this.pageSize = pageSize;
} public int getCurrentPage() {
return currentPage;
} public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
} public int getPageSize() {
return pageSize;
} public void setPageSize(int pageSize) {
this.pageSize = pageSize;
} public int getPrePage() {
return prePage;
} public void setPrePage(int prePage) {
this.prePage = prePage;
} public int getNextPage() {
return nextPage;
} public void setNextPage(int nextPage) {
this.nextPage = nextPage;
} public int getTotalPage() {
return totalPage;
} public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
} public int getTotalCount() {
return totalCount;
} public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
} public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}

mybatis-config.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>
<plugins>
<plugin interceptor="*.*.PageInterceptor"></plugin>
</plugins>
</configuration>

使用:

Map<String, Object> paramMap = new HashMap<String, Object>();
PageParameter pageParameter = new PageParameter();
pageParameter.setCurrentPage(10000);
userService.findUserPage(pageParameter, null);

springMVC分页,interceptor实现的更多相关文章

  1. springmvc之interceptor(拦截器)

    1.自定义MyInterceptor impletments HandlerInterceptor public class MyInterceptor implements HandlerInter ...

  2. SpringMvc中Interceptor拦截器用法

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆等. 一. 使用场景 1 ...

  3. springMVC之Interceptor拦截器

    转自:https://blog.csdn.net/qq_25673113/article/details/79153547 Interceptor拦截器用于拦截Controller层接口,表现形式有点 ...

  4. SpringMVC分页查询无法直接将对象转换成json的解决办法(报org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type:错)

    在用ajax获得分页数据时,无法将获取的值赋值给input标签,在修改用户信息时不显示用户已经注册的信息,百度可知 springmvc处理分页数据返回的对象时,无法直接将对象转换成json,会报org ...

  5. springmvc 异常Interceptor

    无论做什么项目,进行异常处理都是非常有必要的,而且你不能把一些只有程序员才能看懂的错误代码抛给用户去看,所以这时候进行统一的异常处理,展现一个比较友好的错误页面就显得很有必要了. springMVC提 ...

  6. SpringMVC中Interceptor和Filter区别

    Interceptor 主要作用:拦截用户请求,进行处理,比如判断用户登录情况,权限验证,主要针对Action请求进行处理.是通过HandlerInterceptor 实现的. 配置如下: <m ...

  7. springmvc学习笔记--Interceptor机制和实践

    前言: Spring的AOP理念, 以及j2ee中责任链(过滤器链)的设计模式, 确实深入人心, 处处可以看到它的身影. 这次借项目空闲, 来总结一下SpringMVC的Interceptor机制, ...

  8. SpringMVC学习记录5

    Springmvc流程中的扩展点有很多,可以在很多地方插入自己的代码逻辑达到控制流程的目的. 如果要对Controller的handler方法做统一的处理.我想应该会有很多选择,比如:@ModelAt ...

  9. SpringMVC拦截器(实现登录验证拦截器)

    本例实现登陆时的验证拦截,采用SpringMVC拦截器来实现 当用户点击到网站主页时要进行拦截,用户登录了才能进入网站主页,否则进入登陆页面 核心代码 首先是index.jsp,显示链接 <%@ ...

随机推荐

  1. vs如何在C++中调用Lua

    最近Cocos2dx的学习卡壳了,一般的照抄代码我不想写上来,但想示例也想得我头晕...为了放松大脑调整状态于是开始学习Lua.Lua的语法学习还是比较简单的,学过javascript或者vbscri ...

  2. piap.windows io 监测attilax总结

    piap.windows io 监测attilax总结 当硬盘光狂闪的时候. 主要目标:找出哪个进程占用io最多, 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来 ...

  3. iOS-旧项目中手动内存管理(MRC)转ARC

    在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事.我参 加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题, ...

  4. css3使用box-sizing布局

    css3增添了盒模型box-sizing,属性值有下面三个: content-box:默认值,让元素维持W3C的标准盒模型.元素的宽度/高度(width/height)(所占空间)等于元素边框宽度(b ...

  5. RESTORE DATABASE的standby选项

    RESTORE DATABASE [db1] FROM DISK = N'E:\Backup\db2.bak' , MOVE N'db1_Data' TO N'D:\Data\db2.MDF', MO ...

  6. 了解HTML表单之input元素的23种type类型

    目录 传统类型 text password file radio checkbox hidden button image reset submit 新增类型 color tel email url ...

  7. Java多线程系列--“JUC集合”04之 ConcurrentHashMap

    概要 本章是JUC系列的ConcurrentHashMap篇.内容包括:ConcurrentHashMap介绍ConcurrentHashMap原理和数据结构ConcurrentHashMap函数列表 ...

  8. inuit.css – 基于 Sass 的强大,可扩展的 CSS 框架

    inuit.css 是一个强大的,可扩展的 CSS 框架,另外还是基于 Sass,面向对象的框架.inuit.css 是建立在 BEM 风格的命名约定,非常适合于想要专注于创意而不是代码的设计师以及喜 ...

  9. 关于Unicode和URL encoding入门的一切以及注意事项

    本文同时也发表在我另一篇独立博客 <关于Unicode和URL encoding入门的一切以及注意事项>(管理员请注意!这两个都是我自己的原创博客!不要踢出首页!不是转载!已经误会三次了! ...

  10. android中出现Error retrieving parent for item: No resource found that matches the Theme.AppCompat.Light

    styles.xml中<style name="AppBaseTheme" parent="Theme.AppCompat.Light">提示如下错 ...