@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class}), @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
public class PageWidget implements Interceptor {
private static final Logger log = LoggerFactory.getLogger(PageWidget.class);
private String dialect = "mysql";
private String pageMatch = ".*Page$";
@Override
public Object intercept(Invocation invocation) throws Throwable {
if (invocation.getTarget() instanceof StatementHandler) {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
while (metaObject.hasGetter("h")) {
Object object = metaObject.getValue("h");
metaObject = SystemMetaObject.forObject(object);
}
while (metaObject.hasGetter("target")) {
Object object = metaObject.getValue("target");
metaObject = SystemMetaObject.forObject(object);
}
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
if (mappedStatement.getId().matches(pageMatch)) {
BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
String sql = boundSql.getSql();
Assert.notNull(metaObject.getValue("delegate.boundSql.parameterObject"), "parameterObject is null");
PageTool page = (PageTool) metaObject.getValue("delegate.boundSql.parameterObject.pageTool");
boolean needCount = true;
boolean needPage = true;
if (needPage) {
String pageSql = buildPageSql(sql, page);
metaObject.setValue("delegate.boundSql.sql", pageSql);
if (needCount) {
Connection conn = (Connection) invocation.getArgs()[0];
setPageParameters(sql, page, conn, mappedStatement, boundSql);
metaObject.setValue("delegate.boundSql.parameterObject.page", page);
}
}
}
return invocation.proceed();
} else if (invocation.getTarget() instanceof ResultSetHandler) {
Object result = invocation.proceed();
Page page = new Page();
page.setResult((List) result);
System.out.println(page.getResult() + "mark");
return page;
} else {
return null;
}
}
@Override
public Object plugin(Object target) {
if (target instanceof StatementHandler || target instanceof ResultSetHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
@Override
public void setProperties(Properties properties) {
this.dialect = properties.getProperty("dialect");
this.pageMatch = properties.getProperty("pageMatch");
}
private String buildPageSql(String sql, PageTool page) {
Assert.notNull(page, "pageutil is null");
return buildPageSqlForDialect(dialect, sql, page).toString();
}
private StringBuilder buildPageSqlForDialect(String dialect, String sql, PageTool page) {
StringBuilder builder = new StringBuilder();
if ("mysql".equalsIgnoreCase(dialect)) {
builder.append(sql);
builder.append(" LIMIT ").append(page.getPageIndex()).append(",").append(page.getPageSize());
} else {
builder.append(sql);
}
log.debug("分页sql:{}", builder);
if(page.showSql()) {
System.out.println("page sql:\t" + builder);
}
return builder;
}
private void setPageParameters(String sql, PageTool page, Connection connection, MappedStatement mappedStatement, BoundSql boundSql) {
int from = sql.indexOf("FROM");
String countSql = "SELECT COUNT(*) " + sql.substring(from);
if(page.showSql()) {
System.out.println("\npage sql:\t" + countSql);
}
PreparedStatement statement = null;
ResultSet rs = null;
try {
statement = connection.prepareStatement(countSql);
BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), boundSql.getParameterObject());
setParameters(statement, mappedStatement, countBS, boundSql.getParameterObject());
rs = statement.executeQuery();
int totalCount = 0;
if (rs.next()) {
totalCount = rs.getInt(1);
}
page.setPageDataCount(totalCount);
page.setPageCount(page.getPageDataCount() % page.getPageSize() == 0 ? page.getPageDataCount() / page.getPageSize() : (page.getPageDataCount() / page.getPageSize()) + 1);
} catch (SQLException e) {
log.error("PageWidget error get total count:", e);
} finally {
try {
rs.close();
statement.close();
} catch (SQLException e) {
log.error("PageWidget error close rs or stmt:", e);
}
}
}
private void setParameters(PreparedStatement statement, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throws SQLException {
ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler.setParameters(statement);
}
这是我的分页核心类,我通过拦截StatementHandler和ResultSetHandler来实现分页逻辑,前者,是动态更改sql,后者是修改返回类型。现在的问题就下面的代码,有问题,不知道什么原因,为空。
Object result = invocation.proceed(); Page page = new Page(); page.setResult((List) result); System.out.println(page.getResult() + "mark"); return page;
上面的代码,我将查询的结果,放到Page分页对象中,然后并打印出来,并正确显示,但我再次打印page对象时,显示的结果为空。不知道什么原因,就是因为这个page为空,现在导致我的分页返回不了数据返回的值为空。