@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为空,现在导致我的分页返回不了数据返回的值为空。


吉林乌拉
456 声望31 粉丝