private void pagination(Invocation invocation, StatementHandler target) throws SQLException { final MetaObject metaStatementHandler = getMetaObject(target); final BoundSql boundSql = target.getBoundSql(); Page<?> page = PAGE_THREAD_LOCAL.get(); if (page == null) { page = findPageParameter(boundSql.getParameterObject()); } // 如果传入的参数中有分页对象且sql语句中有select,才做分页处理 String sql = boundSql.getSql().toLowerCase(); if (sql.startsWith("select") && page != null) { // 采用物理分页后,就不需要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]; MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement"); if (page.isCountTotal()) { int recordsTotal = getTotalCount(sql, connection, mappedStatement, boundSql); page.setTotalNum(recordsTotal); } // 最后重写sql String pageSql = buildPageSql(sql, page); metaStatementHandler.setValue("delegate.boundSql.sql", pageSql); } }
public Object intercept(Invocation invocation) throws Throwable { StatementHandler handler = (StatementHandler) invocation.getTarget(); MetaObject metaObject = MetaObject.forObject(handler); Page page = pageByMetaObject(metaObject); if (page == null || (page.getPageCount() == 0 && page.getPageSize() == 0)) return invocation.proceed(); Configuration configuration = (Configuration) metaObject.getValue("delegate.configuration"); BoundSql orgBoundSql = (BoundSql) metaObject.getValue("delegate.boundSql"); if (page.getCount() == 0) { MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement"); page.setCount( totalCount( (Connection) invocation.getArgs()[0], orgBoundSql, configuration, mappedStatement)); } metaObject.setValue( "delegate.boundSql.sql", searchDialectByDbTypeEnum(configuration, page) .spellPageSql(orgBoundSql.getSql(), page.getOffset(), page.getLimit())); logger.debug("pagination sql : {}", handler.getBoundSql().getSql()); return invocation.proceed(); }
public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); BoundSql boundSql = statementHandler.getBoundSql(); String sql = tryConvertSql(boundSql); if (StringUtils.isNotEmpty(sql)) { Reflections.setFieldValue(boundSql, "sql", sql); } return invocation.proceed(); }
@Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); ParameterHandler parameterHandler = statementHandler.getParameterHandler(); BoundSql boundSql = statementHandler.getBoundSql(); MetaObject metaStatementHandler = MetaObject.forObject( statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY); RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds"); // 没有分页参数 if (rowBounds == null || rowBounds == RowBounds.DEFAULT) { return invocation.proceed(); } Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration"); Dialect dialect = DialectFactory.buildDialect(configuration); String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql"); // 获取总记录数 Page<?> page = (Page<?>) rowBounds; String countSql = dialect.getCountString(originalSql); Connection connection = (Connection) invocation.getArgs()[0]; int total = getTotal(parameterHandler, connection, countSql); page.setTotalCount(total); // 设置物理分页语句 metaStatementHandler.setValue( "delegate.boundSql.sql", dialect.getLimitString(originalSql, page.getOffset(), page.getLimit())); // 屏蔽mybatis原有分页 metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET); metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT); if (logger.isDebugEnabled()) { logger.debug("分页SQL : " + boundSql.getSql()); } return invocation.proceed(); }
@Override @SuppressWarnings({"unchecked", "rawtypes"}) public Object intercept(Invocation invocation) throws Throwable { if (invocation.getTarget() instanceof StatementHandler) { // 控制SQL和查询总数的地方 Page page = pageThreadLocal.get(); Order order = orderThreadLocal.get(); RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget(); StatementHandler delegate = (StatementHandler) ReflectUtil.getFieldValue(handler, "delegate"); BoundSql boundSql = delegate.getBoundSql(); if (page == null) { // 不是分页查询 if (order != null) { String orderSql = buildOrderSql(order, boundSql.getSql()); ReflectUtil.setFieldValue(boundSql, "sql", orderSql); } return invocation.proceed(); } Connection connection = (Connection) invocation.getArgs()[0]; prepareAndCheckDatabaseType(connection); // 准备数据库类型 if (page.getTotalPage() > -1) { if (log.isTraceEnabled()) { log.trace("已经设置了总页数, 不需要再查询总数."); } } else { Object parameterObj = boundSql.getParameterObject(); MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement"); queryTotalRecord(page, parameterObj, mappedStatement, connection); } String sql = boundSql.getSql(); if (order != null) { sql = buildOrderSql(order, sql); } String pageSql = buildPageSql(page, sql); if (log.isDebugEnabled()) { log.debug("分页时, 生成分页pageSql: " + pageSql); } ReflectUtil.setFieldValue(boundSql, "sql", pageSql); return invocation.proceed(); } else { // 查询结果的地方 try { // 获取是否有分页Page对象 Page<?> page = findPageObject(invocation.getArgs()[1]); // 获取是否有排序Order对象 Order order = findOrderObject(invocation.getArgs()[1]); if (order != null) { orderThreadLocal.set(order); } if (page == null) { if (log.isTraceEnabled()) { log.trace("没有Page对象作为参数, 不是分页查询."); } return invocation.proceed(); } else { if (log.isTraceEnabled()) { log.trace("检测到分页Page对象, 使用分页查询."); } } // 设置真正的parameterObj invocation.getArgs()[1] = extractRealParameterObject(invocation.getArgs()[1]); pageThreadLocal.set(page); Object resultObj = invocation.proceed(); // Executor.query(..) if (resultObj instanceof List) { /* @SuppressWarnings({ "unchecked", "rawtypes" }) */ page.setDatas((List) resultObj); } return resultObj; } finally { pageThreadLocal.remove(); orderThreadLocal.remove(); } } }