Mybatis Plus 插件

Mybatis Plus 求和插件

根据业务需求,需要自动根据业务的 amount 字段求和,实现原理同分页插件

@Data
@EqualsAndHashCode(callSuper = true)
public class SumAmountPage<T> extends Page<T> {

    private Double sumAmount;
}
@Slf4j
public class SumAmountInnerInterceptor implements InnerInterceptor {

    @Override
    public boolean willDoQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);
        if (page == null || page.getSize() < 0 || !page.searchCount() || !(page instanceof SumAmountPage)) {
            return true;
        }
        SumAmountPage<?> sumAmountPage = (SumAmountPage<?>) page;

        MappedStatement mappedStatement = buildMappedStatement(ms);
        String sumAmountSqlStr = autoSumAmountSql(boundSql.getSql());
        PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
        BoundSql sumAmountSql = new BoundSql(mappedStatement.getConfiguration(), sumAmountSqlStr, mpBoundSql.parameterMappings(), parameter);
        PluginUtils.setAdditionalParameter(sumAmountSql, mpBoundSql.additionalParameters());

        CacheKey cacheKey = executor.createCacheKey(mappedStatement, parameter, rowBounds, sumAmountSql);
        List<Object> result = executor.query(mappedStatement, parameter, rowBounds, resultHandler, cacheKey, sumAmountSql);
        if (CollectionUtils.isNotEmpty(result) && Objects.nonNull(result.get(0))) {
            sumAmountPage.setSumAmount((Double) result.get(0));
        }
        return true;
    }

    protected String autoSumAmountSql(String sql) {
        try {
            Select select = (Select) CCJSqlParserUtil.parse(sql);
            PlainSelect plainSelect = (PlainSelect) select.getSelectBody();

            SelectExpressionItem total = new SelectExpressionItem(new Column().withColumnName("sum(amount)")).withAlias(new Alias("sum"));
            plainSelect.setSelectItems(Collections.singletonList(total));
            return select.toString();
        } catch (Exception e) {
            log.error("自动生成统计金额sql失败 {}", sql, e);
        }
        return null;
    }

    protected MappedStatement buildMappedStatement(MappedStatement ms) {
        String sumAmountId = ms.getId() + "_sumAmount";
        Configuration configuration = ms.getConfiguration();
        MappedStatement.Builder builder = new MappedStatement.Builder(configuration, sumAmountId, ms.getSqlSource(), ms.getSqlCommandType());
        builder.resource(ms.getResource());
        builder.fetchSize(ms.getFetchSize());
        builder.statementType(ms.getStatementType());
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());
        builder.resultMaps(Collections.singletonList(new ResultMap.Builder(configuration, Constants.MYBATIS_PLUS, Double.class, Collections.emptyList()).build()));
        builder.resultSetType(ms.getResultSetType());
        builder.cache(ms.getCache());
        builder.flushCacheRequired(ms.isFlushCacheRequired());
        builder.useCache(ms.isUseCache());
        return builder.build();
    }
}
/**
 * @author shalongfei
 */
@EnableTransactionManagement
@Configuration
@MapperScan("")
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 必须放到分页插件前面,因为分页插件会修改SQL
        interceptor.addInnerInterceptor(new SumAmountInnerInterceptor());
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }

}

使用方式也比较简单,如下所示

public SumAmountPage<Payment> query() {
    return this.page(new SumAmountPage<>(), new LambdaQueryWrapper<>());
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值