前后端交互通用排序策略

news2024/11/25 12:49:20

目录

排序场景

排序实现思路

        1. 静态代码排序实现

        2.数据库驱动排序实现

        3. 基于Java反射的动态排序实现

通用排序工具 SortListUtil

结语


排序场景

        在面向前端数据展示的应用场景中,我们旨在实现一个更加灵活的排序机制,该机制能够支持对从后端传递至前端的全部字段进行排序操作。用户通过点击排序按钮,即可实现对特定字段或多字段的升序或降序排列,从而快速实现页面的排序展示效果。

排序实现思路

        1. 静态代码排序实现

  • 内容:后端对前端传递的所有字段进行判断,以编写代码的方式实现排序逻辑
  • 优点:采用静态代码实现排序逻辑的方法简洁明了,能够适应各种不同的场景
  • 缺点:该方法会导致代码冗余,每个报表都需要独立实现排序逻辑,缺乏代码的可复用性

        2.数据库驱动排序实现

  • 内容:基于数据库排序的方式,前端将要排序的字段传给后端,后端转成数据库字段进行排序
  • 优点:当涉及简单字段排序时,利用数据库自身的排序功能可以提高排序效率
  • 缺点:该方法不适用于复合字段(即需要计算得出的字段)或前端字段与数据库字段没有直接映射关系的情况

        3. 基于Java反射的动态排序实现

        

  • 内容:前端传递排序字段和排序方式,排序字段基于后端提供的返回字段。在接口层接收到查询请求后,首先通过业务逻辑层获取到一个尚未排序的数据集合。随后,通过调用一个通用的排序工具来对集合进行排序处理,最终返回经过排序的集合。
  • 优点:采用通用排序工具使得排序逻辑与业务逻辑和应用逻辑分离,利用Java反射机制实现了这一过程,从而显著提升了系统的可扩展性和灵活性。
  • 缺点:Java反射机制的使用会增加资源消耗;同时,它可能会违背封装原则,并有可能引入安全风险。

通用排序工具 SortListUtil

        sortListUtil是一个java语言实现的工具类方法。通过泛型、Comparator和Java 反射机制实现单字段排序,多字段排序。其中sortListByField方法处理集合单字段排序;sortListByFields方法处理集合多字段排序;getComparator方法为通用的排序方法,封装了处理集合排序字段的逻辑,通过这个方法组装成comparator对象,最后统一使用stream().sorted()方法进行排序。

  • 方法内容
package com.streamax.bus.report.server.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Component
@Slf4j
public class SortListUtil<T> {

    public List<T> sortListByField(
            List<T> list, String fieldName, Integer orderBySort) {
        if (fieldName == null || fieldName == "") {
            return list;
        }
        // 构建getter方法名
        String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        Comparator<T> comparator = getComparator(getterName, orderBySort);

        // 使用sorted和collect来排序并收集结果
        return list.stream()
                .sorted(comparator)
                .collect(Collectors.toList());
    }

    /**
     * 多字段排序
     *
     * @param list
     * @param fieldNames
     * @param orderBySort
     * @return
     */
    public List<T> sortListByFields(
            List<T> list, String[] fieldNames, Integer orderBySort) {
        if (fieldNames == null || fieldNames.length == 0) {
            return list;
        }
        Comparator<T> comparator = null;
        for (String fieldName : fieldNames) {
            // 构建getter方法名
            String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            if (comparator == null) {
                comparator = getComparator(getterName, orderBySort);
            } else {
                comparator.thenComparing(getComparator(getterName, orderBySort));
            }
        }
        // 使用sorted和collect来排序并收集结果
        return list.stream()
                .sorted(comparator)
                .collect(Collectors.toList());
    }


    private Comparator<T> getComparator(String getterName, Integer orderBySort) {

        Comparator<T> comparator = (dto1, dto2) -> {
            try {
                Class<?> clazz = dto1.getClass();
                // 获取对应的getter方法
                Method getterMethod = clazz.getMethod(getterName);
                // 调用getter方法获取值
                Object value1 = getterMethod.invoke(dto1);
                Object value2 = getterMethod.invoke(dto2);
                // 关于有值为空的处理
                if (value1 == null || value2 == null) {
                    return (value1 == null) ? (value1 == null ? -1 : 0) : 1;
                }
                // 比较两个值
                if (value1 instanceof Comparable && value2 instanceof Comparable) {
                    if (orderBySort != null && orderBySort == 1) {
                        return ((Comparable) value2).compareTo(value1);
                    }
                    return ((Comparable) value1).compareTo(value2);
                } else {
                    throw new IllegalArgumentException("Field values are not comparable");
                }
            } catch (Exception e) {
                throw new RuntimeException("Error comparing field values", e);
            }
        };
        return comparator;


    }
}

  • 使用方式
  • public static void main(String[] args) {
            QueryParams reqQuery = new QueryParams();
            reqQuery.setOrderByCommon("排序字段");
            reqQuery.setOrderBySort("排序类型 升序,降序");
            ObjectList resultList = new ArrayList<>();
            resultList = new SortListUtil<ObjectList>().sortListByField(resultList, reqQuery.getOrderByCommon(), reqQuery.getOrderBySort());
            
        }
  • resultList : 需要排序的集合
  • reqQuery:前端请求参数
    • orderByCommon:需要排序的字段
    • orderBySort:排序的方式(正序,倒序)

结语

        本文简单阐述了排序功能的实现策略,并提供了一款基于Java反射机制的排序工具类名为SortListUtil。该工具于2024年11月5日上午完成编码,并已通过初步的单元测试和系统测试。需要注意的是,目前提供的版本并非工具类的最终形态。我们欢迎各位同仁提出宝贵的优化建议,共同探讨和提升工具的性能与可用性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2234107.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【华为云-云驻共创】UCS跨云多活容灾:让业务高可用不再是难题

【摘要】云原生应用深入到企业各个业务场景&#xff0c;云原生正在走向分布式化&#xff0c;跨云跨域统一协同治理&#xff0c;保证一致应用体验&#xff0c;这些新的需求日益凸显。而容灾是确保服务高可用的保障&#xff0c;但即使应用部署在云上&#xff0c;也无法避免市政方…

Linux内核编程(十九)SPI子系统的应用与驱动编写

本文目录 一、 SPI驱动框架图二、编写SPI驱动device框架三、编写SPI驱动driver框架四、实验一编写mcp2515驱动1. 注册字符设备或杂项设备框架2. SPI写数据3. SPI读寄存器数据 4. MCP2515相关配置 对于SPI基础知识这里不做过多讲解&#xff0c;详情查看&#xff1a;SPI基础知识实…

谍影重重5.0

打开流量包可以发现&#xff0c;流量中含有大量的smb加密通信&#xff0c;并且使用了ntlm v2加密协议进行身份认证 包过滤ntlmssp 认证后smb协议进行了大量的数据传输 取出tom的包内数据 得到以下数据 username:tomdomain: .NTProofStr: ca32f9b5b48c04ccfa96f35213d63d75NT…

qt QAbstractItemModel详解

1. 概述 QAbstractItemModel是Qt框架中的一个核心抽象基类&#xff0c;在Qt的模型/视图架构中扮演着至关重要的角色。这个类提供了一个接口&#xff0c;用于表示和管理数据&#xff0c;但不直接处理数据的存储。它的主要功能是为视图组件&#xff08;如QListView、QTableView和…

华为OD机试 - 无重复字符的元素长度乘积的最大值(Python/JS/C/C++ 2024 C卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

【C++之STL】一文学会使用 string

文章目录 1. STL导读1. 1 什么是STL1. 2 STL的版本1. 3 STL六大组件1. 4 STL的重要性1. 5 STL的学习1. 6 STL系列博客的规划 2. string2. 1 为什么学习string类?2. 2 标准库中的string2. 3 基本构造2. 4 尾插与输出运算符重载2. 5 构造函数2. 6 赋值运算符重载2. 7 容量操作2.…

【分布式】分布式锁设计与Redisson源码解析

分布式锁 分布式锁是一种在分布式计算环境中用于控制多个节点&#xff08;或多个进程&#xff09;对共享资源的访问的机制。在分布式系统中&#xff0c;多个节点可能需要协调对共享资源的访问&#xff0c;以防止数据的不一致性或冲突。分布式锁允许多个节点在竞争访问共享资源…

【实测有效】两个Ubuntu系统通过网线传输文件

基本思路是&#xff1a;连接网线后&#xff0c;通过设置静态IP&#xff0c;将两台电脑配置在同一个局域网内&#xff0c;再进行文件传输。 一、物理连接 使用网线将两台电脑的网口连接起来。 二、静态IP设置 两台电脑均需要对各自的静态IP进行设置。 1、查看电脑的IP地址 1&a…

Android camera2

一、序言 为了对阶段性的知识积累、方便以后调查问题&#xff0c;特做此文档&#xff01; 将以camera app 使用camera2 api进行分析。 (1)、打开相机 openCamera (2)、创建会话 createCaptureSession (3)、开始预览 setRepeatingRequest (4)、停止预览 stopRepeating (5)、关闭…

【Redis_Day3】Redis通用命令

【Redis_Day3】Redis通用命令 redis客户端的三种形态redis的快与慢redis通用命令阅读redis官方文档redis中两个核心命令set命令get命令 redis全局命令keys命令&#xff1a;查询当前服务器上的key生产环境 exists命令&#xff1a;判定key是否存在del命令&#xff1a;删除指定的k…

静态库、动态库、framework、xcframework、use_frameworks!的作用、关联核心SDK工程和测试(主)工程、设备CPU架构

1.1库的概念 库&#xff1a;程序代码的集合&#xff0c;编译好的二进制文件加上头文件供使用&#xff0c;共享程序代码的一种方式。 1.2库的分类 根据开源情况分为&#xff1a;开源库&#xff08;能看到具体实现&#xff09;、闭源库&#xff08;只公开调用的的接口&#xf…

小菜家教平台:基于SpringBoot+Vue打造一站式学习管理系统

前言 现在已经学习了很多与Java相关的知识&#xff0c;但是迟迟没有进行一个完整的实践&#xff08;之前这个项目开发到一半&#xff0c;很多东西没学搁置了&#xff0c;同时原先的项目中也有很多的问题&#xff09;&#xff0c;所以现在准备从零开始做一个基于SpringBootVue的…

【C++、数据结构】哈希表——散列表(一)(概念/总结)

「前言」 &#x1f308;个人主页&#xff1a; 代码探秘者 &#x1f308;C语言专栏&#xff1a;C语言 &#x1f308;C专栏&#xff1a; C / STL使用以及模拟实现 &#x1f308;数据结构专栏&#xff1a; 数据结构 / 十大排序算法 &#x1f308;Linux专栏&#xff1a; Linux系统编…

山东路远生态科技有限公司竣工投产仪式暨产品发布会圆满举行

第二十届三中全会于2024年7月15日至18日在北京举行。全会审议通过了《关于进一步全面深化改革、推进中国式现代化的决定》。其中提到,“要健全因地制宜发展新质生产力体制机制”。 新质生产力是由技术革命性突破、生产要素创新性配置、产业深度转型升级而催生的当代先进生产力…

MD5(Crypto)

解题思路 打开文件发现一串代码&#xff0c;结合题目提示&#xff0c;应该是 MD5 加密。 找个在线的 MD5 解密网站&#xff0c;行云流水得到 flag。 题目设计原理 题目设计&#xff1a;无他&#xff0c;MD5 加密。 题目原理&#xff1a; MD5&#xff08;Message-Digest Algo…

EHOME视频平台EasyCVR萤石设备视频接入平台视频诊断技术可以识别哪些视频质量问题?

EasyCVR视频监控汇聚管理平台是一款针对大中型项目设计的跨区域网络化视频监控集中管理平台。萤石设备视频接入平台EasyCVR不仅具备视频资源管理、设备管理、用户管理、运维管理和安全管理等功能&#xff0c;还支持多种主流标准协议&#xff0c;如GB28181、GB35114、RTSP/Onvif…

QML项目实战:自定义Button

目录 一.添加模块 ​1.QtQuick.Controls 2.1 2.QtGraphicalEffects 1.12 二.自定义Button 1.颜色背景设置 2.设置渐变色背景 3.文本设置 4.点击设置 5.阴影设置 三.效果 1.当enabled为true 2.按钮被点击时 3.当enabled为false 四.代码 一.添加模块 1.QtQuick.Con…

实战攻略 | ClickHouse优化之FINAL查询加速

【本文作者&#xff1a;擎创科技资深研发 禹鼎侯】 查询时为什么要加FINAL 我们在使用ClickHouse存储数据时&#xff0c;通常会有一些去重的需求&#xff0c;这时候我们可以使用ReplacingMergeTree引擎。这个引擎允许你存储重复数据&#xff0c;但是在merge的时候会根据order …

labview学习总结

labview学习总结 安装labview的特点一、图形化编程范式二、并行执行机制三、硬件集成能力四、应用领域优势五、开发效率六、系统集成能力**labview基本组成示意图****常用程序结构图解**结语 基础知识介绍界面前后面板的概念平铺式和层叠式 帧的概念结构类型顺序结构for循环whi…

Linux 服务器使用指南:从入门到登录

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; &#x1f6a9;博主致力于用通俗易懂且不失专业性的文字&#xff0c;讲解计算机领域那些看似枯燥的知识点&#x1f6a9; 目录 一…