前后端交互通用排序策略

目录

排序场景

排序实现思路

        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.mzph.cn/diannao/59402.shtml

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

相关文章

java 中List 的使用

List集合是Collection接口的子接口&#xff0c;其下有两个实现类分别为ArrayList和 LinkedList List是一个接口&#xff0c;不能用new创建对象&#xff0c;需要用 ArrayList类 和 LinkedList类 来创建 特点 有序&#xff1a;存储元素的顺序和取出元素的顺序一致可以重复&…

MD5(Crypto)

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

跟李沐学AI:BERT

什么是NLP中的迁移学习 使用预训练好的模型来抽取词、句子的特征&#xff1a;Word2Vec或者预训练好的语言模型。 使用预训练好的语言模型&#xff0c;一般不会再对语言模型进行微调&#xff0c;即不进行更新。 Word2Vec一般用于替代embedding层 但是Word2Vec往往忽略了时序…

时间段比较与 SQL 实现:交集、并集与补集

文章目录 时间段比较与 SQL 实现&#xff1a;交集、并集与补集时间段比较的六种基本情况SQL 实现&#xff1a;时间段的交集、并集和补集判断两个时间段是否有交集取两个时间段的交集取两个时间段的并集取两个时间段的补集处理多个时间段的交集和并集结合补集与交集 实际应用与优…

单元/集成测试解决方案

在项目开发的前期针对软件单元/模块功能开展单元/集成测试&#xff0c;可以尽早地发现软件Bug&#xff0c;避免将Bug带入系统测试阶段&#xff0c;有效地降低HIL测试的测试周期&#xff0c;也能有效降低开发成本。单元/集成测试旨在证明被测软件实现其单元/架构设计规范、证明被…

C语言复习第9章 字符串/字符/内存函数

目录 一、字符串函数1.1 读取字符串gets函数原型Example 1.2 字符串拷贝strcpy函数原型模拟实现官方源码 1.3 求字符串长度strlen函数原型关于返回值size_与算术转换的一个易错点模拟实现:递归模拟实现:指针-指针模拟实现:暴力官方源码 1.4 字符串追加strcat函数原型注意自己给…

WPF 特性------Binding

工业控制中&#xff0c;经常会需要把一个bool 型输入信号的状态显示在面板上&#xff0c;使用wpf 绑定的办法&#xff0c;可简洁实现&#xff1a; 实现步骤&#xff1a; 1&#xff0c;定义类&#xff1a; using System; using System.Collections.Generic; using System.Com…

在 Spring Boot 中使用分布式事务时,如何处理不同数据源之间的事务一致性问题?

在 Spring Boot 中使用分布式事务处理不同数据源之间的事务一致性问题&#xff0c;可以考虑以下几种方法&#xff1a; 一、使用分布式事务框架 Seata&#xff1a; Seata 是一款开源的分布式事务解决方案。它通过对业务无侵入的方式&#xff0c;提供了 AT&#xff08;Automatic …

Docker Compose部署XXL-JOB

整个工具的代码都在Gitee或者Github地址内 gitee&#xff1a;solomon-parent: 这个项目主要是总结了工作上遇到的问题以及学习一些框架用于整合例如:rabbitMq、reids、Mqtt、S3协议的文件服务器、mongodb github&#xff1a;GitHub - ZeroNing/solomon-parent: 这个项目主要是…

[spark面试]spark与mapreduce的区别---在DAG方面

1、spark中的task是以线程实现的&#xff0c;而mapreduce中是以进程实现的。 进程的频繁启动和停止会增加资源的消耗。 2、spark中支持DAG&#xff0c;而mapreduce不支持DAG DAG的使用&#xff1a;为什么支持DAG会更加高效 1&#xff09;、在DAG图中&#xff0c;会将一个job…

【React】react-app-env.d.ts 文件

在使用 create-react-app 生成的 TypeScript 项目模板中&#xff0c;react-app-env.d.ts 文件的作用是为 React 应用中的全局变量和类型进行声明。 全局类型声明&#xff1a;react-app-env.d.ts 文件会引入 react-scripts 提供的全局类型定义&#xff0c;这些类型定义扩展了 Ty…

软件测试(系统测试)的定位和专业:完善产品;专业;非助手;自动化

软件测试&#xff08;系统测试&#xff09;的定位 在研发流程的后端&#xff0c;测试并非无中生有的创举&#xff0c;而是从既有基础&#xff08;即“1”&#xff09;出发&#xff0c;致力于推动产品向更高层次&#xff08;即从“1”到“100”&#xff09;的跃升与完善。在这一…

【MySQL】深层理解索引及特性(重点)--下(12)

索引&#xff08;重点&#xff09; 1. 索引的作用2. 索引操作2.1 主键索引2.1.1 主键索引的特点2.1.2 创建主键索引 2.2 唯一键索引2.2.1 唯一键索引的特点2.2.2 唯一索引的创建 2.3 普通索引2.3.1 普通索引的特点2.3.2 普通索引的创建 2.4 全文索引2.4.1 全文索引的作用2.4.2 …

基于SpringBoot+微信小程序+协同过滤算法+二维码订单位置跟踪的农产品销售平台-新

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; “农产品商城”小程序…

udp丢包问题

udp或者tcp丢包问题监测方式&#xff1a; netstat -su 问题分析&#xff1a; 1. 内存 2. cpu 3. 发送接收缓存 动画图解 socket 缓冲区的那些事儿-CSDN博客

09.外观模式设计思想

09.外观模式设计思想 目录介绍 01.外观模式基础 1.1 外观模式由来1.2 外观模式定义1.3 外观模式场景1.4 外观模式思考1.5 解决的问题 02.外观模式实现 2.1 罗列一个场景2.2 外观结构2.3 外观基本实现2.4 有哪些注意点2.5 设计思想 03.外观实例演示 3.1 需求分析3.2 代码案例实…

电机轴设计的技术参数研究

电机轴作为电机的关键组件之一&#xff0c;其设计不仅关系到电机的性能和效率&#xff0c;还直接影响到整个机械系统的可靠性与使用寿命。电机轴的设计涉及众多技术参数&#xff0c;这些参数通常包括但不限于尺寸参数、材料选择、强度分析、转动平衡、轴承选择以及制造公差等。…

个人开发三步走

一、开发准备 1&#xff0e;需求分析&#xff1a;需求是开发的起点。第一步要做的就是明确需求&#xff0c;具体来说就是分析目标用户、他们的需求(功能需求、性能需求、安全需求)和痛点。 2&#xff0e;技术选型&#xff1a;综合开发需求、个人能力&#xff08;能熟练使用&a…

C++ | Leetcode C++题解之第541题反转字符串II

题目&#xff1a; 题解&#xff1a; class Solution { public:string reverseStr(string s, int k) {int n s.length();for (int i 0; i < n; i 2 * k) {reverse(s.begin() i, s.begin() min(i k, n));}return s;} };

一个由Deno和React驱动的静态网站生成器

大家好&#xff0c;今天给大家分享一个由 Deno React 驱动的静态网站生成器Pagic。 项目介绍 Pagic 是一个由 Deno React 驱动的静态网站生成器。它配置简单&#xff0c;支持将 md/tsx 文件渲染成静态页面&#xff0c;而且还有大量的官方或第三方主题和插件可供扩展。 核心…