mybatisplus order by 使用mysql cast函数丢失空格问题

文章讲述了在SpringBoot项目中,如何通过MyBatisPlus处理VARCHAR类型的金额字段进行排序,以及遇到的MySQL识别问题,最终通过自定义QueryWrapper类解决cast函数在orderby中的使用问题。
摘要由CSDN通过智能技术生成

        最近有个需求,需要通过mysql 中 某张表的 varchar2 类型字段(保存数据为金额)进行 asc 或 desc 排序。项目框架为 springboot + mybatisplus 。

        优化方案有:

                一:重新设计表结构,将金额字段设计为 DECIMAL(18,4)。重写相关代码,最后进行测试,周期较长。由于本项目相关字段的业务不是很重。所以放弃!

                二:使用 cast(column as DECIMAL)进行转换 后 order by。采用此种写法。

        

        实现代码:

    public BsPage<Entity> queryList(Integer page, Integer rows, Map<String, Object> params) {
        BsPage<Entity> bsPage = new BsPage<>(page, rows);
        String objId = params.get("objId") != null ? params.get("objId").toString() : null;
        String keyWord = params.get("keyWord") != null ? params.get("keyWord").toString() : null;
        String sortType = params.get("sortKey") != null ? params.get("sortKey").toString() : null;
        QueryWrapper<Entity> wrapper = new QueryWrapper<>();
        wrapper.eq(objId != null, "obj_id", objId);
        wrapper.and(StrUtil.isNotBlank(keyWord), i -> i.like("title", keyWord).or().like("purchaser", keyWord));
        wrapper.orderByAsc(sortType!=null && "publishDate_asc".equals(sortType), "publish_date");
        wrapper.orderByDesc(sortType!=null && "publishDate_desc".equals(sortType), "publish_date");
        wrapper.orderByAsc( sortType!=null && "bidAmount_asc".equals(sortType)," cast(bid_amount as DECIMAL) ");
        wrapper.orderByDesc(sortType!=null && "bidAmount_desc".equals(sortType), " cast(bid_amount as DECIMAL) ");

        return baseMapper.selectPage(bsPage, wrapper);
    }

主要有:

wrapper.orderByAsc( sortType!=null && "bidAmount_asc".equals(sortType)," cast(bid_amount as DECIMAL) ");

wrapper.orderByDesc(sortType!=null && "bidAmount_desc".equals(sortType), " cast(bid_amount as DECIMAL) ");

运行结果报错:

SELECT * FROM table WHERE (obj_id = ?) ORDER BY cast(bid_amountasDECIMAL) DESC

追源码,发现 mybatisplus 底层将  cast(bid_amount as DECIMAL) 以 单个字段名的方式进行去空格。导致 mysql 无法识别。

源码位置:

AbstractWrapper.java 中使用 columnSqlInjectFilter 方法

@Deprecated
@Override
public Children orderBy(boolean condition, boolean isAsc, R column, R... columns) {
    return maybeDo(condition, () -> {
        final SqlKeyword mode = isAsc ? ASC : DESC;
        appendSqlSegments(ORDER_BY, columnToSqlSegment(columnSqlInjectFilter(column)), mode);
        if (ArrayUtils.isNotEmpty(columns)) {
            Arrays.stream(columns).forEach(c -> appendSqlSegments(ORDER_BY,
                columnToSqlSegment(columnSqlInjectFilter(c)), mode));
        }
    });
}

具体实现方法:

QueryWrapper.java 

@Override
protected String columnSqlInjectFilter(String column) {
    return StringUtils.replaceBlank(column);
}

因此:需要自己覆盖 QueryWrapper 的 columnSqlInjectFilter 方法。使用时在业务层 使用 即可。

代码:

/**
 * 重写 mybatisplus 的查询类,mybatisplus 查询时 orderby 不可使用函数 。
 *  如 :order by cast(bid_amount as DECIMAL) 。mybatisplus 会将其转换为 ORDER BY cast(bid_amountasDECIMAL) ASC
 * 
 */
public class PcQueryWrapper<T> extends QueryWrapper<T> {

    @Override
    protected String columnSqlInjectFilter(String column) {
        return column;
    }

}

业务层使用 new PcQueryWrapper 的方式使用。

@Override
public BsPage<Entity> queryList(Integer page, Integer rows, Map<String, Object> params) {
    BsPage<Entity> bsPage = new BsPage<>(page, rows);
    String objId = params.get("objId") != null ? params.get("objId").toString() : null;
    String keyWord = params.get("keyWord") != null ? params.get("keyWord").toString() : null;
    String sortType = params.get("sortKey") != null ? params.get("sortKey").toString() : null;
//    QueryWrapper<Entity> wrapper = new QueryWrapper<>();
    PcQueryWrapper<Entity> wrapper = new PcQueryWrapper<>();
    wrapper.eq(objId != null, "obj_id", objId);
    wrapper.and(StrUtil.isNotBlank(keyWord), i -> i.like("title", keyWord).or().like("purchaser", keyWord));
    wrapper.orderByAsc(sortType!=null && "publishDate_asc".equals(sortType), "publish_date");
    wrapper.orderByDesc(sortType!=null && "publishDate_desc".equals(sortType), "publish_date");
    wrapper.orderByAsc( sortType!=null && "bidAmount_asc".equals(sortType)," cast(bid_amount as DECIMAL) ");
    wrapper.orderByDesc(sortType!=null && "bidAmount_desc".equals(sortType), " cast(bid_amount as DECIMAL) ");

    return baseMapper.selectPage(bsPage, wrapper);
}

执行结果:

SELECT * FROM table WHERE (obj_id = ?) ORDER BY  cast(bid_amount as DECIMAL)  ASC

完结!!!

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值