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

📚目录

  • 📚简介
  • 💨优化前原代码:
  • ⚙️ 函数编程简化
    • 🎄 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.hqwc.cn/news/295326.html

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

相关文章

ebay万圣节活动攻略,ebay万圣节活动怎么弄?-站斧浏览器

ebay万圣节活动攻略 提前准备&#xff1a;为了确保在活动期间能够及时上架商品并制定营销策略&#xff0c;卖家需要提前做好准备。了解活动规则和时间表&#xff0c;提前准备好商品和营销策略&#xff0c;以便在活动期间迅速响应市场需求。 优化商品列表&#xff1a;在活动期…

2024年个人目标制定清单~有没有适合你的那一款

在2024年&#xff0c;个人的生活目标可以有多种多样&#xff0c;这主要取决于个人的价值观、兴趣和生活情况。 个人生活目标&#xff1a; 健康和健身&#xff1a;保持身体健康和良好的心理状态是许多人重要的生活目标。这可能包括定期运动&#xff0c;均衡饮食&#xff0c;以…

【ElfBoard】ELF 1 开箱初体验

大家好&#xff0c;我是 Hello阿尔法&#xff0c;最近参与了保定飞凌嵌入式技术有限公司举办的 ElfBoard 共创社招募活动&#xff0c;并有幸成为了一名共创官&#xff0c;官方寄来了一块 ELF 1 开发板&#xff0c;开箱视频看这里 飞凌嵌入式「ElfBoard」开箱体验&#xff01;。…

“比特币教父”发声力保铭文!拥堵问题可通过发展L2来解决!比特币比以太坊更需要L2?

继12月6日比特币核心开发者Luke公开发文抵制铭文后&#xff0c;比特币教父Adam Back近日提出了不同的观点。他认为不应该试图扼杀比特币铭文&#xff0c;因为在比特币链上发行资产给比特币矿工带来巨大的收益&#xff0c;对比特币的长期稳定发展是有价值的&#xff0c;而比特币…

高频知识汇总 | 【操作系统】面试题汇总(万字长博通俗易懂)

前言 这篇我亲手整理的【操作系统】资料&#xff0c;融入了我个人的理解。当初我在研习八股文时&#xff0c;深感复习时的困扰&#xff0c;网上资料虽多&#xff0c;却过于繁杂&#xff0c;有的甚至冗余。例如&#xff0c;文件管理这部分&#xff0c;在实际面试中很少涉及&…

Flutter 三: Dart

1 数据类型 数字(number) int double 字符串转换成 num int.parse(“1”) double.parse(“1”);double 四舍五入保留两位小数 toStringAsFixed(2) 返回值为stringdouble 直接舍弃小数点后几位的数据 可使用字符串截取的方式 字符串(string) 单引号 双引号 三引号三引号 可以输…

MySQL数据库基础和基本的增删改查操作

目录 前瞻 数据库的基本概念 数据库管理系统&#xff08;DBMS&#xff09; 数据库系统(DBS) 数据库类型和常用数据库 关系型数据库 SQL 非关系型数据库 NoSQL SQL语句 简介 SQL语句分类 常用的数据类型 MySQL的六大约束特性 SQL语句的使用 创建及删除数据库和表 …

会员管理怎么做?

会员管理是企业运营的重要组成部分&#xff0c;它涉及到会员的招募、维护、激励、保留、转化等多个环节。下面&#xff0c;我们将结合具体的案例&#xff0c;详细介绍会员管理的具体做法。 首先&#xff0c;会员的招募是会员管理的第一步 企业需要通过各种方式吸引消费者成为会…

【YOLOV8预测篇】使用Ultralytics YOLO进行检测、分割、姿态估计和分类实践

目录 一 安装Ultralytics 二 使用预训练的YOLOv8n检测模型 三 使用预训练的YOLOv8n-seg分割模型 四 使用预训练的YOLOv8n-pose姿态模型 五 使用预训练的YOLOv8n-cls分类模型 <

08-JVM调优实战及常量池详解

文章目录 阿里巴巴Arthas详解Arthas使用场景Arthas使用 GC日志详解打印GC日志方法如何分析GC日志CMSG1 JVM参数汇总查看命令Class常量池与运行时常量池字面量符号引用 字符串常量池字符串常量池的设计思想三种字符串操作(Jdk1.7 及以上版本)字符串常量池位置字符串常量池设计原…

量化服务器 - 后台挂载运行

服务器 - 后台运行 pip3命令被kill 在正常的pip命令后面加上 -no-cache-dir tmux 使用教程 https://codeleading.com/article/40954761108/ 如果你希望在 tmux 中后台执行一个 Python 脚本&#xff0c;你可以按照以下步骤操作&#xff1a; 启动 tmux: tmux这将会创建一个新…

设计模式篇---职责链模式

文章目录 概念结构实例总结 概念 职责链模式&#xff1a;避免将一个请求的发送者与接收者耦合在一起&#xff0c;让多个对象都有机会处理请求。将接收请求的对象连接成一条链&#xff0c;并且沿着这条链传递请求&#xff0c;直到有一个对象能够处理它为止。 比如大学期间&…