package com.wporoad.app.util;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
//import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import javax.xml.bind.PropertyException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
* Mybatis - 通用分页拦截器v3.1.0
*
* @author liuzh/abel533/isea
* Created by liuzh on 14-4-15.
* Update by liuzh on 14-5-20.
* Update by liuzh on 14-5-21.
*/
@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class PageHelper implements Interceptor {
private static final ThreadLocal<Page> localPage = new ThreadLocal<Page>();
private static final List<ResultMapping> EMPTY_RESULTMAPPING = new ArrayList<ResultMapping>(0);
private static String dialect = ""; //数据库方言
/**
* 开始分页
*
* @param pageNum
* @param pageSize
*/
public static void startPage(int pageNum, int pageSize) {
startPage(pageNum, pageSize, true);
}
/**
* 开始分页
*
* @param pageNum
* @param pageSize
*/
public static void startPage(int pageNum, int pageSize, boolean count) {
localPage.set(new Page(pageNum, pageSize, count? Page.SQL_COUNT: Page.NO_SQL_COUNT));
}
@Override
public Object intercept(Invocation invocation) throws Throwable {
final Object[] args = invocation.getArgs();
RowBounds rowBounds = (RowBounds)args[2];
if (localPage.get() == null && rowBounds == RowBounds.DEFAULT) {
return invocation.proceed();
} else {
//忽略RowBounds-否则会进行Mybatis自带的内存分页
args[2] = RowBounds.DEFAULT;
MappedStatement ms = (MappedStatement) args[0];
Object parameterObject = args[1];
BoundSql boundSql = ms.getBoundSql(parameterObject);
//分页信息
Page page = localPage.get();
//移除本地变量
localPage.remove();
if (page == null) {
page = new Page(rowBounds);
}
MappedStatement qs = newMappedStatement(ms, new BoundSqlSqlSource(boundSql));
//将参数中的MappedStatement替换为新的qs,防止并发异常
args[0] = qs;
MetaObject msObject = MetaObject.forObject(qs);
String sql = (String) msObject.getValue("sqlSource.boundSql.sql");
//简单的通过total的值来判断是否进行count查询
if (page.getTotal() > Page.NO_SQL_COUNT) {
//求count - 重写sql
msObject.setValue("sqlSource.boundSql.sql", getCountSql(sql));
//查询总数
Object result = invocation.proceed();
int totalCount = (Integer)((List) result).get(0);
page.setTotal(totalCount);
int totalPage = totalCount / page.getPageSize() + ((totalCount % page.getPageSize() == 0) ? 0 : 1);
page.setPages(totalPage);
//分页sql - 重写sql
msObject.setValue("sqlSource.boundSql.sql", getPageSql(sql, page));
//恢复类型
msObject.setValue("resultMaps", ms.getResultMaps());
//执行分页查询
result = invocation.proceed();
//得到处理结果
page.addAll((List) result);
//返回结果
return page;
} else {
//分页sql - 重写sql
msObject.setValue("sqlSource.boundSql.sql", getPageSql(sql, page));
//恢复类型
msObject.setValue("resultMaps", ms.getResultMaps());
//返回结果
return invocation.proceed();
}
}
}
/**
* 获取总数sql - 如果要支持其他数据库,修改这里就可以
* @param sql
* @return
*/
private String getCountSql(String sql) {
return "select count(0) from (" + sql + ") as tmp_count";
}
/**
* 获取分页sql - 如果要支持其他数据库,修改这里就可以
* @param sql
* @param page
* @return
*/
private String getPageSql(String sql, Page page) {
StringBuilder pageSql = new StringBuilder(200);
if("mysql".equals(dialect)){
pageSql.append(sql);
pageSql.append(" limit "+page.getStartRow()+","+page.getPageSize());
}else if("oracle".equals(dialect)){
pageSql.append("select * from ( select temp.*, rownum row_id from ( ");
pageSql.append(sql);
pageSql.append(" ) temp where rownum <= ").append(page.getEndRow());
pageSql.append(") where row_id > ").append(page.getStartRow());
}
return pageSql.toString();
}
private class BoundSqlSqlSource implements SqlSource {
BoundSql boundSql;
public BoundSqlSqlSource(BoundSql boundSql) {
this.boundSql = boundSql;
}
public BoundSql getBoundSql(Object parameterObject) {
return boundSql;
}
}
/**
* 由于MappedStatement是一个全局共享的对象,因而需要复制一个对象来进行操作,防止并发访问导致错误
*
* @param ms
* @param newSqlSource
* @return
*/
private MappedStatement newMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
MappedStatement.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());
if (ms.getKeyProperties() != null && ms.getKeyProperties().length != 0) {
StringBuffer keyProperties = new StringBuffer();
for (String keyProperty : ms.getKeyProperties()) {
keyProperties.append(keyProperty).append(",");
}
keyProperties.delete(keyProperties.length() - 1, keyProperties.length());
builder.keyProperty(keyProperties.toString());
}
builder.timeout(ms.getTimeout());
builder.parameterMap(ms.getParameterMap());
//由于resultMaps第一次需要返回int类型的结果,所以这里需要生成一个resultMap - 防止并发错误
List<ResultMap> resultMaps = new ArrayList<ResultMap>();
ResultMap resultMap = new ResultMap.Builder(ms.getConfiguration(), ms.getId(), int.class, EMPTY_RESULTMAPPING).build();
resultMaps.add(resultMap);
builder.resultMaps(resultMaps);
builder.resultSetType(ms.getResultSetType());
builder.cache(ms.getCache());
builder.flushCacheRequired(ms.isFlushCacheRequired());
builder.useCache(ms.isUseCache());
return builder.build();
}
/**
* 只拦截Executor
*
* @param target
* @return
*/
@Override
public Object plugin(Object target) {
if (target instanceof Executor) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
public void setProperties(Properties p) {
dialect = p.getProperty("dialect");
if (dialect!=null&&dialect.equals("")) {
try {
throw new PropertyException("dialect propert
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
SSM框架 Mybatis项目示例代码 (104个子文件)
PageHelper.class 9KB
UserAction.class 4KB
Page.class 3KB
PageModel.class 3KB
UserServiceTest.class 2KB
UserServiceImpl.class 2KB
Test.class 2KB
DBInit.class 1KB
User.class 1KB
PageHelper$BoundSqlSqlSource.class 881B
UserService.class 444B
UserMapper.class 438B
.classpath 607B
org.eclipse.wst.common.component 471B
org.eclipse.wst.jsdt.ui.superType.container 49B
aspectjtools.jar 8.57MB
aspectjweaver.jar 1.67MB
freemarker-2.3.19.jar 909KB
org.springframework.context-3.1.2.RELEASE.jar 813KB
struts2-core-2.3.4.jar 765KB
mybatis-3.1.1.jar 636KB
xwork-core-2.3.4.jar 614KB
javassist-3.11.0.GA.jar 600KB
org.springframework.beans-3.1.2.RELEASE.jar 578KB
org.springframework.web.servlet-3.1.2.RELEASE.jar 564KB
commons-collections-3.2.1.jar 562KB
org.springframework.web-3.1.2.RELEASE.jar 536KB
mysql-connector-java-5.0.8-bin.jar 528KB
mybatis-generator-core-1.3.2.jar 504KB
log4j-1.2.16.jar 470KB
org.springframework.core-3.1.2.RELEASE.jar 439KB
org.springframework.jdbc-3.1.2.RELEASE.jar 395KB
standard.jar 384KB
org.springframework.orm-3.1.2.RELEASE.jar 371KB
org.springframework.aop-3.1.2.RELEASE.jar 325KB
commons-lang3-3.1.jar 308KB
cglib-2.2.2.jar 280KB
commons-lang-2.4.jar 256KB
org.springframework.transaction-3.1.2.RELEASE.jar 239KB
org.springframework.test-3.1.2.RELEASE.jar 224KB
ognl-3.0.5.jar 222KB
org.springframework.jms-3.1.2.RELEASE.jar 194KB
org.springframework.web.portlet-3.1.2.RELEASE.jar 186KB
org.springframework.expression-3.1.2.RELEASE.jar 172KB
commons-dbcp-1.4.jar 157KB
commons-io-2.0.1.jar 156KB
aspectjrt.jar 112KB
commons-pool-1.6.jar 109KB
org.springframework.context.support-3.1.2.RELEASE.jar 105KB
org.springframework.oxm-3.1.2.RELEASE.jar 71KB
commons-logging-1.1.1.jar 59KB
commons-fileupload-1.2.2.jar 58KB
org.springframework.asm-3.1.2.RELEASE.jar 52KB
org.springframework.aspects-3.1.2.RELEASE.jar 49KB
asm-3.3.1.jar 43KB
mybatis-spring-1.1.1.jar 40KB
org.springframework.web.struts-3.1.2.RELEASE.jar 30KB
slf4j-api-1.6.0.jar 25KB
struts2-spring-plugin-2.3.4.jar 21KB
jstl.jar 20KB
org.springframework.instrument.tomcat-3.1.2.RELEASE.jar 11KB
slf4j-log4j12-1.6.0.jar 10KB
org.springframework.instrument-3.1.2.RELEASE.jar 7KB
aopalliance-1.0.jar 4KB
PageHelper.java 8KB
UserAction.java 4KB
PageModel.java 4KB
Page.java 3KB
UserServiceImpl.java 1KB
Test.java 1KB
User.java 924B
UserServiceTest.java 849B
UserService.java 826B
DBInit.java 778B
UserMapper.java 765B
.jsdtscope 500B
UserList2.jsp 2KB
UserList.jsp 922B
update.jsp 879B
index.jsp 687B
detail.jsp 570B
success.jsp 457B
error.jsp 408B
MANIFEST.MF 36B
.mymetadata 306B
org.eclipse.wst.jsdt.ui.superType.name 6B
org.eclipse.jdt.core.prefs 364B
.project 2KB
log4j.properties 583B
log4j.properties 583B
jdbc.properties 104B
jdbc.properties 104B
test.sql 186B
test.sql 186B
struts.xml 2KB
struts.xml 2KB
applicationContext.xml 2KB
applicationContext.xml 2KB
UserMapper.xml 2KB
UserMapper.xml 2KB
共 104 条
- 1
- 2
资源评论
- songyanhong2062017-09-25希望好用啊啊啊啊
- nuomi972016-07-12不错的资源 学习了
- 夏夜虫飞2018-07-11不错的资源 学习了
qq330800037
- 粉丝: 6
- 资源: 9
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Screenshot_20240427_031602.jpg
- 网页PDF_2024年04月26日 23-46-14_QQ浏览器网页保存_QQ浏览器转格式(6).docx
- 直接插入排序,冒泡排序,直接选择排序.zip
- 在排序2的基础上,再次对快排进行优化,其次增加快排非递归,归并排序,归并排序非递归版.zip
- 实现了7种排序算法.三种复杂度排序.三种nlogn复杂度排序(堆排序,归并排序,快速排序)一种线性复杂度的排序.zip
- 冒泡排序 直接选择排序 直接插入排序 随机快速排序 归并排序 堆排序.zip
- 课设-内部排序算法比较 包括冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、归并排序和堆排序.zip
- Python排序算法.zip
- C语言实现直接插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序、归并排序、计数排序,并带图详解.zip
- 常用工具集参考用于图像等数据处理
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功