前后端交互通用排序策略

news/2024/11/6 5:08:55 标签: 交互, java

目录

排序场景

排序实现思路

        1. 静态代码排序实现

        2.数据库驱动排序实现

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

通用排序工具 SortListUtil

结语


排序场景

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

排序实现思路

        1. 静态代码排序实现

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

        2.数据库驱动排序实现

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

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

        

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

通用排序工具 SortListUtil

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

  • 方法内容
java">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;


    }
}

  • 使用方式
  • java">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.niftyadmin.cn/n/5740215.html

相关文章

大模型算法工程师经典面试题————Transformer中 前馈层(FFN) 的作用是什么?

什么是 前馈层&#xff08;FFN&#xff09;? Transformer的前馈层通常包含哪些组件&#xff1f; Transformer中 前馈层&#xff08;FFN&#xff09; 的作用是什么&#xff1f; 什么是 前馈层&#xff08;FFN&#xff09;? 前馈层&#xff08;FFN&#xff09;本质上就是一…

【LuatOS】修改LuatOS源码为PC模拟器添加高精度时间戳库timeplus

0x00 缘起 LuatOS以及Lua能够提供微秒或者毫秒的时间戳获取工具&#xff0c;但并没有提供获取纳秒的工具。通过编辑LuatOS源码以及相关BSP源码&#xff0c;添加能够获取纳秒的timeplus库并重新编译&#xff0c;以解决在64位Windows操作系统中LuatOS模拟器获取纳秒的问题&#…

51单片机教程(八)- 数码管的静态显示

1、项目分析 使用数码管显示指定的字符、数字和符号。 2、技术准备 1、显示器及其接口 单片机系统中常用的显示器有&#xff1a; 发光二极管LED&#xff08;Light Emitting Diode&#xff09;显示器、液晶LCD&#xff08;Liquid Crystal Display&#xff09;显示器、CRT显…

网络技术----wireshark抓包出现1500以上的大包原因分析

网络技术----wireshark抓包出现1500以上的大包原因分析 背景描述原因分析TSO&#xff08;TCP segment offload&#xff0c;TSO&#xff09;linux中关闭/开启TSO功能&#xff1a;其他类似TSO的机制 wireshark抓包来源 背景描述 我们在使用抓包工具的过程中&#xff0c;经常发现…

基于MATLAB的农业病虫害识别研究

1 背景介绍 病虫害一直是限制农业生产过程中农业和副产品的高质量和高产量的最重要因素。然而&#xff0c;在识别中国的病虫害时&#xff0c;无论是用肉眼识别的传统方法还是后来专家的系统判断&#xff0c;这些病虫害的特征一般都是主观因素。主观意图非常大&#xff0c;效率…

pdf添加目录标签python(手动配置)

先安装对应的库: pip install pypdf 代码分为两个部分,一部分是config.py,代码如下: offset=10 catgorys=[("第一章",12),("第二章",45), ] 需要自己手动更改offset,和目录列表 下面是主要代码: import pypdf # import sys from config import…

Intellij IDE报错:[Information:java:javacTask:源发行版8需要目标发行版1.8]

Intellij IDE报错:[Information:java:javacTask:源发行版8需要目标发行版1.8] 处理方法 File->Settings->Build,execution,Deployment->Compiler->Java Compiler 进入该目录下&#xff0c;修改Per-module bytecode version&#xff0c;将该项目修改为8 合理的创…

java mapper 的 xml讲解

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace"com.bnc.s12.mapper.GoodaCateDT…