程序员的每日进阶系列—动态排序

我们在写代码的时候经常会碰到这样的需求
1、列表查询默认xxx字段升/降序
2、按照列表内的某字段进行升/降序排序,当有两条数据一致则按照xxx字段升/降序排序。
例如:
在这里插入图片描述
在这里,我们默认按照新建时间降序排序,如果点击审批额度/日息 则按照他们中的一个进行升/降序排序如果查出的数据有重复的重复部分进行创建时间降序排序。

是不是觉得很绕?
捋一下思路:

  1. 没有条件选择查询默认创建时间降序排序

  2. 点击审批额度/日息,则以审批额度/日息为排序字段进行升降序排序

    2.1、当查询的数据显示两条重复的则对重复部分进行创建时间降序排序

这是你会发现,逻辑非常清晰了

默认排序规则:创建时间降序排序
     第一排序规则:这里是审批日期和日息(按照你们的需求字段来)
     第二排序规则:创建时间

思路清晰了 开始设计方案:
1、直接sql实现排序业务逻辑
2、sql只管条件查询的结果,排序逻辑放到业务层代码进行处理(使用stream流进行操作)

方案1、优点:直接将业务逻辑压力放到数据库,数据库的查询效率是非常高的,所以优点就是查询效率高
             缺点:无法处理非常复杂的业务逻辑,业务越复杂,查询时间会成倍的增加

方案2、优点:业务逻辑放到业务层进行梳理,将压力给了服务器端,解放了数据库,因此可以处理更加复杂的业务逻辑
              缺点:查询效率低,服务器压力大

具体实现:

方案1、

 String orderBy = "";
           //如果审批日期排序字段不为空
            if (null != queryBO.getLoanLimitSort()) {
             //审批日期降序
                if (queryBO.getLoanLimitSort() == 0) {
                    orderBy += "floanlimit desc,fcreatetime desc";

                } else if (queryBO.getLoanLimitSort() == 1) {
                    orderBy += "floanlimit,fcreatetime desc";
                }
            }
             //如果日息排序字段不为空
            if (null != queryBO.getInterestSort()) {
                if (queryBO.getInterestSort() == 0) {
                    orderBy +="finterest desc,fcreatetime desc";
                } else if (queryBO.getInterestSort() == 1) {
                    orderBy +="finterest asc,fcreatetime desc";
                }
            }
               queryBO.setOrderBy(orderBy);
          list = proManagerDao.listByCondition(queryBO);

配合sql

select
        fproductid as productId,
        fproductname as productName,
        fphone as phone,
        finterest as interest,
        floanlimit as loanLimit,
        frepaymentperiod as repaymentPeriod,
        fapprovaltime as approvalTime,
        fintroduction as introduction,
        feffect as effect,
        fproductimg as productImg,
        fapplicanttype as applicantType,
        foperator as operator,
        fprotocol as protocol,
        DATE_FORMAT(fupdatetime,'%Y-%m-%d %T') as updateTime,
        DATE_FORMAT(fcreatetime,'%Y-%m-%d %T') as createTime
        from t_management_product
        where 1=1
        <if test="productName !=null and productName !=''">
            and  fproductname like concat('%',#{productName},'%')
        </if>
        <if test="bankName !=null and bankName !=''">
            and  fbankname like concat('%',#{bankName},'%')
        </if>
        <if test="contact !=null and contact !=''">
            and  fcontacts like concat('%',#{contact},'%')
        </if>
        order by
        <choose>
            <when test="orderBy != null and orderBy != ''">
                ${orderBy}
            </when>
            <otherwise>
                fcreatetime desc
            </otherwise>
        </choose>

采用了sql拼接方式进行实现,如果排序规则没有这么复杂可以直接使用进行判断

方案2、业务层

   list = proManagerDao.listByCondition(queryBO);
            if (null != queryBO.getLoanLimitSort()) {
                if (queryBO.getLoanLimitSort() == 0) {
                   return list.stream().sorted(Comparator.comparing(ProductManageVO::getLoanLimit).reversed()).collect(Collectors.toList());

                } else if (queryBO.getLoanLimitSort() == 1) {
                    return list.stream().sorted(Comparator.comparing(ProductManageVO::getLoanLimit)).collect(Collectors.toList());
                }
            }
            if (null != queryBO.getInterestSort()) {
                if (queryBO.getInterestSort() == 0) {
                    return list.stream().sorted(Comparator.comparing(ProductManageVO::getInterest).reversed()).collect(Collectors.toList());
                } else if (queryBO.getInterestSort() == 1) {
                    return list.stream().sorted(Comparator.comparing(ProductManageVO::getInterest)).collect(Collectors.toList());
                }
            }

配合sql

select
        fproductid as productId,
        fproductname as productName,
        fcontacts as contacts,
        fphone as phone,
        fbankid as bankId,
        fbankname as bankName,
        finterest as interest,
        floanlimit as loanLimit,
        frepaymentperiod as repaymentPeriod,
        fapprovaltime as approvalTime,
        fintroduction as introduction,
        feffect as effect,
        fproductimg as productImg,
        fapplicanttype as applicantType,
        foperator as operator,
        fprotocol as protocol,
        DATE_FORMAT(fupdatetime,'%Y-%m-%d %T') as updateTime,
        DATE_FORMAT(fcreatetime,'%Y-%m-%d %T') as createTime
        from t_management_product
        where 1=1
        <if test="productName !=null and productName !=''">
            and  fproductname like concat('%',#{productName},'%')
        </if>
        <if test="bankName !=null and bankName !=''">
            and  fbankname like concat('%',#{bankName},'%')
        </if>
        <if test="contact !=null and contact !=''">
            and  fcontacts like concat('%',#{contact},'%')
        </if>
        order by createTime desc
     

第二种方式是对查询出来的结果进行一个数据流处理,所以对于一些分页工具,是无法使用的,因为分页工具是对sql执行进行一个动态切面管理,而无法对执行后得到的数据进行一个分页处理

好了,动态排序就聊到这了,咱们下次见!!!

发布了47 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42083036/article/details/105515922
今日推荐