使用函数式接口对代码简化,完成代码重复性使用

📚目录

  • 📚简介
  • 💨优化前原代码:
  • ⚙️ 函数编程简化
    • 🎄 JDK自带的函数式接口
    • ✨ 改造调用方式
      • 🎊 时间范围执行
      • 🎉时间范围每天执行

📚简介

       因为公司的使用Xxl-Job作为任务调度平台,其中我们大部分的报表查询数据量太大,字段又多,实时查询效率太低,等待时长也久,我们只能把常用的数据进行定时任务处理,每几分钟自动运行程序跑对应报表的Sql插入缓存表中,页面端在通过缓存表进行渲染,使用这点有个不好之处就是有个定时任务的执行时间差,关于订单业绩相关的我们任务设置的时间就短,尽量不影响使用者.
       所以这个时间我们需要传递查询指定时间范围内,或者是不指定时间而是指定运行前多少天的数据进行重跑处理.最终参数定义了常用的三个参数

{"beginTime":"","endTime":"","beforeDays":"10"
}

xxl-job 的参数接收类

在这里插入图片描述

💨优化前原代码:

伪代码:缓存定时任务

/*** @Author itmei* @Date 2023/12/22 20:48* @description: 任务处理器* @Title: CacheTaskHandle* @Package com.itmei.xxl.task*/
@Component
public class CacheTaskHandle {@XxlJob("bxCacheTableTask")public ReturnT<String> bxCacheTableTask() throws Exception {long start = System.currentTimeMillis();//获取xxl-job调度传递过来的数据String param = XxlJobHelper.getJobParam();XxlJobHelper.log("###### Job参数 ######\n{}",param);XxlJobParam jobParam;if (ObjectUtil.isNotEmpty(param)) {jobParam = JSONUtil.toBean(param, XxlJobParam.class);} else {jobParam = new XxlJobParam();}DateTime beginTime;DateTime endTime;if (ObjectUtil.isEmpty(jobParam.getBeginTime()) || ObjectUtil.isEmpty(jobParam.getEndTime())) {DateTime startDateTime;DateTime endDateTime = DateUtil.date();Integer beforeDays = jobParam.getBeforeDays();if (ObjectUtil.isEmpty(beforeDays)) {//默认开始时间是当前时间向之前偏移46天startDateTime = DateUtil.offsetDay(new Date(), -46);} else {startDateTime = DateUtil.offsetDay(new Date(), -Integer.valueOf(beforeDays));}beginTime = DateUtil.beginOfDay(startDateTime);endTime = DateUtil.endOfDay(endDateTime);} else {//处理时间范围beginTime = DateUtil.beginOfDay(jobParam.getBeginTime());endTime = DateUtil.endOfDay(jobParam.getEndTime());}bxCacheHandle(beginTime,endTime);long end = System.currentTimeMillis();XxlJobHelper.log("###### Job执行完成,耗时: {} 秒 ######",(end-start)/1000);return ReturnT.SUCCESS;}@XxlJob("bwmCacheTableTask")public ReturnT<String> bwmCacheTableTask() throws Exception {long start = System.currentTimeMillis();//获取xxl-job调度传递过来的数据String param = XxlJobHelper.getJobParam();XxlJobHelper.log("###### Job参数 ######\n{}",param);XxlJobParam jobParam;if (ObjectUtil.isNotEmpty(param)) {jobParam = JSONUtil.toBean(param, XxlJobParam.class);} else {jobParam = new XxlJobParam();}DateTime beginTime;DateTime endTime;if (ObjectUtil.isEmpty(jobParam.getBeginTime()) || ObjectUtil.isEmpty(jobParam.getEndTime())) {DateTime startDateTime;DateTime endDateTime = DateUtil.date();Integer beforeDays = jobParam.getBeforeDays();if (ObjectUtil.isEmpty(beforeDays)) {//默认开始时间是当前时间向之前偏移46天startDateTime = DateUtil.offsetDay(new Date(), -46);} else {startDateTime = DateUtil.offsetDay(new Date(), -Integer.valueOf(beforeDays));}beginTime = DateUtil.beginOfDay(startDateTime);endTime = DateUtil.endOfDay(endDateTime);} else {//处理时间范围beginTime = DateUtil.beginOfDay(jobParam.getBeginTime());endTime = DateUtil.endOfDay(jobParam.getEndTime());}bwmCacheHandle(beginTime,endTime);long end = System.currentTimeMillis();XxlJobHelper.log("###### Job执行完成,耗时: {} 秒 ######",(end-start)/1000);return ReturnT.SUCCESS;}public void bxCacheHandle(Date startTime, Date endTime) {/*** 伪代码,不能泄密,单纯打印看效果*/XxlJobHelper.log("{}       {}-{} {}       ", "bxCacheTableTask",startTime.toString(),endTime.toString(),"查询缓存数据...");XxlJobHelper.log("{}       插入数据         ", "bxCacheTableTask");}public void bwmCacheHandle(Date startTime, Date endTime) {/*** 伪代码,不能泄密,单纯打印看效果*/XxlJobHelper.log("{}       {}-{} {}       ", "bwmCacheTableTask",startTime.toString(),endTime.toString(),"查询缓存数据...");XxlJobHelper.log("{}       插入数据         ", "bwmCacheTableTask");}
}

在这里插入图片描述

       这些代码都是复用的,除了bxCacheHandle(beginTime,endTime);是处理对应缓存表的逻辑代码,当我需要创建新的缓存表时,我都会把上面的代码复制下来修改@XxlJob("执行名称"),在把bxCacheHandle(beginTime,endTime);修改成对应缓存表查询处理的逻辑,而且他们共同点就是传入的参数都是开始时间和结束时间,并且没有返回值,那么我们就可以使用BiConsumer<T, U>函数式接口来解决.

在这里插入图片描述

       其实除了时间范围内进行查询,我们还有用到按照传入的时间范围,在按照一天一天维度进行查询,这样的效果就是有些报表一次性查询范围30天会比较久,而且数据库的压力也会提升,我们就需要按照模式去选择,一次性查询一个月还是一个月分30次一天一天的去查询数据.

⚙️ 函数编程简化

我们创建一个专门处理时间查询的类

/*** @Author itmei* @Date 2023/12/23 14:27* @description: 时间范围处理* @Title: DateQueryHandle* @Package com.itmei.xxl.task*/
public class DateQueryHandle {/*** 执行* @param syncLogic 是一个函数式接口 BiConsumer<Date, Date> 的实例,用于执行具体的逻辑。该函数式接口接受两个 Date 类型的参数,分别表示开始时间和结束时间* @param queryType true 一天一天查询 , false 日期区间查询*/public static void execute(BiConsumer<Date,Date> syncLogic,Boolean queryType){long start = System.currentTimeMillis();//获取xxl-job调度传递过来的数据String param = XxlJobHelper.getJobParam();XxlJobHelper.log("###### Job参数 ######\n{}",param);XxlJobParam jobParam;if (ObjectUtil.isNotEmpty(param)) {jobParam = JSONUtil.toBean(param, XxlJobParam.class);} else {jobParam = new XxlJobParam();}DateTime beginTime;DateTime endTime;if (ObjectUtil.isEmpty(jobParam.getBeginTime()) || ObjectUtil.isEmpty(jobParam.getEndTime())) {DateTime startDateTime;DateTime endDateTime = DateUtil.date();Integer beforeDays = jobParam.getBeforeDays();if (ObjectUtil.isEmpty(beforeDays)) {//默认开始时间是当前时间向之前偏移46天startDateTime = DateUtil.offsetDay(new Date(), -46);} else {startDateTime = DateUtil.offsetDay(new Date(), -Integer.valueOf(beforeDays));}beginTime = DateUtil.beginOfDay(startDateTime);endTime = DateUtil.endOfDay(endDateTime);} else {//处理时间范围beginTime = DateUtil.beginOfDay(jobParam.getBeginTime());endTime = DateUtil.endOfDay(jobParam.getEndTime());}if (queryType) {// 按天查询long days = DateUtil.between(beginTime, endTime, DateUnit.DAY);for (int i = 0; i <= days; i++) {DateTime dateTime = DateUtil.offsetDay(beginTime, i);DateTime begin = DateUtil.beginOfDay(dateTime);DateTime end = DateUtil.endOfDay(dateTime);//调用传入的函数式接口实例的方法来执行具体的逻辑syncLogic.accept(begin, end);}} else {//调用传入的函数式接口实例的方法来执行具体的逻辑syncLogic.accept(beginTime, endTime);}long end = System.currentTimeMillis();XxlJobHelper.log("###### Job执行完成,耗时: {} 秒 ######",(end-start)/1000);}/*** 执行* @param syncLogic*/public static void execute(BiConsumer<Date,Date> syncLogic){//重载方法 使用时间范围内的查询execute(syncLogic,false);}
}

🎄 JDK自带的函数式接口

       唯一不一样的是使用了 JDK 1.8 中函数式接口BiConsumer,这个接口默认可以传递2个参数.除了这个JDK 1.8 中还提供了这些常用的函数式接口:

Consumer<T>:接受一个输入参数 T,没有返回值。
Supplier<T>:不接受任何输入参数,返回一个结果 T。
Function<T, R>:接受一个输入参数 T,返回一个结果 R。
Predicate<T>:接受一个输入参数 T,返回一个布尔值。
UnaryOperator<T>:接受一个输入参数 T,返回一个结果 T,输入类型和返回类型相同。
BinaryOperator<T>:接受两个输入参数 T,返回一个结果 T,输入类型和返回类型相同。
BiConsumer<T, U>:接受两个输入参数 T 和 U,没有返回值。
BiFunction<T, U, R>:接受两个输入参数 T 和 U,返回一个结果 R。
BiPredicate<T, U>:接受两个输入参数 T 和 U,返回一个布尔值。

       由于我们简化的代码中并没有返回值,而且需要传入2个参数,这样我们就选择了BiConsumer<T, U>做为本次使用到的函数式接口.

✨ 改造调用方式

🎊 时间范围执行

我们改造bwmCacheTableTask代码,改成函数式接口方式调用

在这里插入图片描述

运行结果

在这里插入图片描述
在这里插入图片描述

改造后,我们只需要一行代码就可以,完成了代码的复用性

在这里插入图片描述

改造后的运行结果和改造前运行结果是一样的,这样是不是代码就更简化

在这里插入图片描述

🎉时间范围每天执行

改造bxCacheTableTask代码为,时间范围内,一天一天的执行效果

在这里插入图片描述

执行效果

在这里插入图片描述

按照时间范围内,进行一天一天查询

在这里插入图片描述

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

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

相关文章

camera同步信号

基本概念 PCLK&#xff1a;pixel clock是像素点同步时钟信号, 主频。也就是每个PCLK对应一个像素点。 HSYNC&#xff1a;horizonal synchronization是行同步信号&#xff0c;水平同步信号。就是在告诉接收端&#xff1a;“HSYNC”有效时段内接收端接收到的所有的信号输出属同…

系列二十八、如何在Oracle官网下载JDK的api文档

一、官网下载JDK的api文档 1.1、官网地址 https://www.oracle.com/java/technologies/javase-jdk21-doc-downloads.html 1.2、我分享的api.chm 链接&#xff1a;https://pan.baidu.com/s/1Bf55Fz-eMTErmQDtZZcewQ?pwdyyds 提取码&#xff1a;yyds 1.3、参考 https://ww…

C语言——高精度除法

一、引子 1、引言 高精度除法相较于加减乘法更加复杂&#xff0c;它需要处理的因素更多&#xff0c;在这里我们先探讨高精度数除以低精度数&#xff0c;即大数除小数。这已满足日常所需&#xff0c;如需大数除以大数&#xff0c;可以使用专门的库&#xff0c;例如&#xff1a…

Angular 11到升级到 Angular 16

日新月异&#xff0c;与时俱进… 随着Angular版本不断更新&#xff0c;再看所开发的项目版本仍然是Angular 11&#xff0c;于是准备升级 截止发博日最版本是 v17.1.0&#xff0c;考虑到稳定性因素决定升级到v16版本 一&#xff1a;查看 升级指南 二&#xff1a;按照指南&…

推荐算法架构7:特征工程(吊打面试官,史上最全!)

系列文章&#xff0c;请多关注 推荐算法架构1&#xff1a;召回 推荐算法架构2&#xff1a;粗排 推荐算法架构3&#xff1a;精排 推荐算法架构4&#xff1a;重排 推荐算法架构5&#xff1a;全链路专项优化 推荐算法架构6&#xff1a;数据样本 推荐算法架构7&#xff1a;特…

数据校园服务管理系统,教育平台可视化界面(教育资源信息化PS文件)

大屏组件可以让UI设计师的工作更加便捷&#xff0c;使其更高效快速的完成设计任务。现分享大数据校园服务管理系统、科技教育平台大数据可视化界面、教育资源信息化大数据分析等Photoshop源文件&#xff0c;文末提供完整资料&#xff0c;供UI设计师们工作使用。 若需其他 大屏…

Linux一行命令配置jdk环境

使用方法&#xff1a; 压缩包上传 到/opt, 更换命令中对应的jdk包名即可。 注意点&#xff1a;jdk-8u151-linux-x64.tar.gz 解压后名字是jdk1.8.0_151 sudo tar -zxvf jdk-8u151-linux-x64.tar.gz -C /opt && echo export JAVA_HOME/opt/jdk1.8.0_151 | sudo tee -a …

unity中使用protobuf工具将proto文件转为C#实体脚本

unity中使用protobuf工具将proto文件转为C#实体脚本 介绍优点缺点Protobuf 为什么比 XML 快得多&#xff1f;Protobuf的EncodingProtobuf封解包的过程通常编写一个Google Protocol Buffer应用需要以下几步&#xff1a; Protostuff是什么Protobuf工具总结 介绍 protobuf也就是G…

Java面向对象(初级)

面向对象编程(基础) 面向对象编程&#xff08;OOP&#xff09;是一种编程范式&#xff0c;它强调程序设计是围绕对象、类和方法构建的。在面向对象编程中&#xff0c;程序被组织为一组对象&#xff0c;这些对象可以互相传递消息。面向对象编程的核心概念包括封装、继承和多态。…

Vue3选项式API和组合式API详解

前言 相信学习Vue3的人中大多数都是之前使用Vue2开发的&#xff0c;当拿到一个Vue3项目时就接触到了组合式api&#xff0c;但对于组合式api不了解的人第一眼看上去会觉得一头雾水。&#xff1a;“什么玩意&#xff0c;乱七八糟的&#xff0c;选项式api多好&#xff0c;方法变量…

Linux bridge开启hairpin模拟测试macvlan vepa模式

看到网上介绍可以通过Linux bridge 开启hairpin方式测试macvlan vepa模式&#xff0c;但是没有找到详细资料。我尝试测试总提示错误信息&#xff0c;无法实现&#xff0c;经过几天的研究&#xff0c;我总算实现模拟测试&#xff0c;记录如下&#xff1a; 参考 1.Linux Macvla…

「Vue3面试系列」Vue3.0性能提升主要是通过哪几方面体现的?

文章目录 一、编译阶段diff算法优化静态提升事件监听缓存SSR优化 二、源码体积三、响应式系统参考文献 一、编译阶段 回顾Vue2&#xff0c;我们知道每个组件实例都对应一个 watcher 实例&#xff0c;它会在组件渲染的过程中把用到的数据property记录为依赖&#xff0c;当依赖发…

MicroPython的交互式解释器模式 REPL

MicroPython的交互式解释器模式又名REPL&#xff08;read-eval-print-loop&#xff09;&#xff0c;就是一种命令输入交互模式&#xff0c;跟Python的REPL是类似的&#xff0c;就是在命令行直接输入Python代码或表达式执行并打印结果。关于MicroPython的REPL跟通常的Python类似…

linux运维面试题

linux运维面试题 面试 K8S篇(高可用) Q&#xff1a;k8s是什么&#xff1f;架构&#xff1f; Kubenetes是一个开源的容器集群管理系统。主要用于容器编排&#xff0c;解决容器调度问题。当应用请求时&#xff0c;k8s需要合理分配请求到空闲node节点上去。k8s使用的主从模式&…

python通过JS逆向采集艺恩电影数据, 并制作可视化

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 环境使用: 版 本&#xff1a; python 3.10 编辑器&#xff1a;pycharm 2022.3.2 nodejs 模块使用: requests -> pip install requests execjs -> pip install…

【Git】在 IDEA 中合并多个 commit 为一个

文章目录 1 未提交到远程分支1.1 需求说明1.2 reset 操作1.3 再次 push 2 已经提交到远程分支2.1 需求说明2.2 rebase 操作2.3 强制 push 分两种情况&#xff1a; 一种是本地提交还没推到远程&#xff0c;这种好处理另一种是已经提交到远程分支&#xff0c;这个略麻烦 1 未提…

【接口测试】Postman(三)-变量与集合

一、变量 ​ 变量这个概念相信大家都不陌生&#xff0c;因此在这里我们不介绍了。主要说一下在Postman中有哪几类变量&#xff0c;主要包括以下四类&#xff1a; Global&#xff08;全局&#xff09; Environment&#xff08;环境&#xff09; Local&#xff08;本地&#xf…

Linux中安装Maven3.6.1

一、安装及配置maven 1.下载maven安装包 首先需要切换到自己需要安装的目录 我自己是把配置都放到了&#xff1a;/usr/local/maven路径下 cd /usr/local/maven 下载maven安装包&#xff1a; wget https://archive.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven…

FreeRTOS信号量学习

目录 一、信号量的特性 1. 信号量的常规操作 2. 信号量跟队列的对比 3. 两种信号量的对比 4. 信号量函数 4.1 创建 4.2 删除 4.3 give/take 5. 使用二进制信号量来同步 6. 防止数据丢失 7. 使用计数型信号量 队列(queue)可以用于传输数据&#xff1a;在任务之间、任务和…

Linux多线程:线程池(单例),读写锁

目录 一、线程池&#xff08;单例模式&#xff09;1.1 makefile1.2 LockGuard.hpp1.3 log.hpp1.4 Task.hpp1.5 Thread.hpp1.6 ThreadPool.hpp1.7 main.cc 二、STL,智能指针和线程安全2.1 STL中的容器是否是线程安全的?2.2 智能指针是否是线程安全的? 三、其他常见的各种锁四、…