如何在报表中实现算法的可挂接需求

在报表项目中,有些报表中部分数据的计算方法会经常改变。例如:某企业员工的实际工资是通过绩效得分计算出的,而绩效的算法可能经常变动,需要在不改动其他代码的情况下用新算法替换旧算法。一般我们都会想到用 Java 来实现计算,从而实现动态可挂接计算模块,但是这种方式可能存在缺乏基础类库、占用多余内存等问题。

这里我们介绍一种可以实现低耦合、热部署的动态挂接算法,使得解决此类问题更具结构性优势,这就是结合集算器使用润乾报表。下图对比了润乾报表实现的可挂接算法和其他报表工具 +java 实现可挂接算法的在系统结构上的差异:

可以看出,java 程序必须要编译、打包才能更新,无法实现热部署。而集算脚本是解释执行的,脚本文件同时也是可执行文件,所以可以直接进行替换更新。同时,集算脚本可以和报表模板成对存放,在代码管理上更为清晰、便利。

下面就用员工绩效工资的例子来说明润乾报表的实现方法,并和其他报表工具 +Java 的实现方式做一下比较。

员工绩效工资报表如下:

报表格式比较简单,但是计算方法相对复杂,而且经常变动,算法部分需要动态挂接才能满足需求。

具体实现步骤如下:

1、编写集算器脚本

                                                                                                                                                     
 ABC
1=connect("demo")  
2=A1.query("select p.EMPLOYEEID as empID, p.EVALUATION as score,e.dept as dept, e.NAME as empName,p.BONUS as baseSalary  from performance as p,employee as e where p.EMPLOYEEID=e.EID  and e.gender=?",gender)
3=A2.derive(PRETAX)  
4=sales=A3.select(DEPT=="Sales") 
5for salesif A5.BASESALARY<2000>A5.PRETAX=A5.BASESALARY*(1+A5.SCORE/100)
6 else if A5.BASESALARY<4000>A5.PRETAX=A5.BASESALARY*(1+A5.SCORE*0.9/100)
7 else if A5.BASESALARY<6000>A5.PRETAX=A5.BASESALARY*(1+A5.SCORE*0.8/100)
8 else>A5.PRETAX=A5.BASESALARY*(1+A5.SCORE*0.6/100)
9=normal=A3.select(DEPT!="Sales") 
10=A9.run(PRETAX=BASESALARY) 
11=sales|normal  
12=A11.new(EMPNAME,BASESALARY,PRETAX)>A1.close()
13result A12  

A2 单元格有个输入参数 gender,来自于查询页面。A13 单元格是将结果返回给报表页面。A2 到 A12 之间是绩效工资的计算方法,具体算法不是本文重点,这里不详细介绍,只要知道这部分可以随时替换就可以了。

2、配置报表数据集

润乾报表的报表模板可以定义集算器数据集来调用可挂接计算模块:

其中,gender 参数是 dynamic.dfx 的输入参数,数据集 ds1 接收 dynamic.dfx 返回的结果集。

可以看到集算器脚本 dynamic.dfx 和报表模板之间的耦合程度非常低。如果要改变绩效工资的计算方法,只需要编写一个新的 dynamic.dfx,替换服务器上原有的 dfx 文件即可。因为 dfx 脚本是解释执行的,所以可以不停机替换,实现真正的热部署。

3、设计报表模板

在润乾报表设计器中像使用普通数据集一样设计报表模板即可。如下图所示:

从这个例子可以看出润乾报表实现的可挂接算法,相比普通报表工具 +Java 的实现方式有多方面的优势。

1、dynamic.dfx 可以使用润乾报表提供的多种函数方法:分组、汇总、排序、过滤、关联、唯一值、交集、排名等等。Java 程序员必须手工编写这些基础算法。而将这些基础算法直接实现在业务逻辑中显然是不合理的,因为这会导致每个计算模块重复书写类似的代码,使得计算模块过于庞大、可读性变差。理想的作法是先实现一套基础算法类库,再在计算模块中调用,而应用程序员很难设计出完备性和系统性优秀的基础算法类库,因此常常使代码的耦合性高,稳定性差,最终导致计算模块维护困难。

润乾报表的集算引擎本身就是这样一套精心设计的完备基础类库,经过简单的学习,应用程序员只需要 JAVA 十分之一的代码量就可以实现同样功能的计算模块,开发效率更高。

2、JAVA 代码需要重新编译,部署起来比较麻烦;当可挂接的计算模块较多时,不论是否还要使用它们,这些 Java class/jar 都会占据内存空间而无法释放,对性能有一定的影响。

润乾报表的集算器引擎和脚本文件是分开的,耦合性很低,维护起来更加方便。另外,集算脚本无需编译即可使用,是真正的热部署。脚本程序不会事先加载到内存,而是使用时再加载,计算完立刻释放,不会长期占用内存。

转载于:https://www.cnblogs.com/IBelieve002/p/10918067.html

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

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

相关文章

【数据结构】字符串匹配|BF算法|KMP算法|next数组的优化

字符串匹配算法是在实际工程中经常遇到的问题&#xff0c;也是各大公司笔试面试的常考题目&#xff0c;本文主要介绍BF算法&#xff08;最好想到的算法&#xff0c;也最好实现&#xff09;和KMP算法&#xff08;最经典的&#xff09; 一、BF算法 BF算法&#xff0c;即暴力(Bru…

JMeter【第五篇】关联:5种方法

前几天在Q群里看到群友发的最近10年性能测试工具使用率的统计&#xff0c;最近的2018年&#xff0c;jmeterloadrunner占了93%的使用率&#xff0c;说明这两个是主流&#xff0c;其中&#xff0c;jmeter的使用率逐年提升&#xff0c;现在已经超过了loadrunner&#xff0c;占了51…

树——通用树到二叉树的转换

1&#xff0c;已经创建了通用树结构&#xff0c;有必要创建另一种树结构吗&#xff1f; 2&#xff0c;简化树就直接减少结点中孩子的数量&#xff0c;但是这样树还能通用吗&#xff1f; 3&#xff0c;通用树结构的回顾&#xff1a; 1&#xff0c;双亲孩子表示法&#xff1a; 1&…

如何运行exe文件

有三种方式 第一种&#xff1a;找到所在文件双击运行。 第二种&#xff1a;在命令行里面运行所在文件夹的位置&#xff0c;在输入文件名。 第三种&#xff1a;加到环境变量里面执行 转载于:https://www.cnblogs.com/q2546/p/10931956.html

推荐几款提升效率的神器

1 数学公式神器&#xff1a;Mathpix Snip 作为理工科的学生或者经常用到数学的科研工作者&#xff0c;应该对数学公式都很头疼&#xff0c;不管是用LaTeX还是mathtype&#xff0c;都比较麻烦&#xff0c;要么需要频繁的鼠标点击&#xff0c;要么需要好的记忆力。而Mathpix Snip…

实验9 c++

problem &#xff1a;A 第一个类 #include <iostream> #include <iomanip> #include <cstring> #include <cmath> using namespace std;class Thing { private:string name; public:Thing(){}Thing(string n):name(n) {cout << "" <…

迭代器协议、斐波那契数列

f1.__iter__iter(f1)  把一个对象变成可迭代对象 __init__  构造函数 for循环遵循迭代器协议&#xff0c;要求对象有next、iter方法&#xff0c;有iter方法&#xff0c;for循环跟着对象对触发对象的方法&#xff08;协议规定&#xff09; 对象内部要有next方法 斐波那契数列…

如何用一个例子彻底解释白盒测试中语句覆盖、判定覆盖、条件覆盖、条件判定覆盖、条件组合覆盖?

白盒测试 白盒测试把测试对象看作一个打开的盒子&#xff0c;测试人员依据程序内部逻辑结构相关信息&#xff0c;设计或选择测试用例&#xff0c;对程序所有逻辑路径进行测试&#xff0c;通过在不同点检查程序的状态&#xff0c;确定实际的状态是否与预期的状态一致。 语句覆…

简易的实现对象内存池

简易的实现对象内存池MemoryNode结构体是保存每一个申请的内存节点&#xff0c;然后构成一个单链表。MemoryNodeList 结构体是保存的是每一块内存&#xff0c;当上一个内存块用完时&#xff0c;再次创建一个内存块。numofMemoryNode&#xff1a;一个内存块的内存节点数量 numof…

Linux关机操作

转载于:https://www.cnblogs.com/hlc-123/p/10958108.html

JAVA:贪吃蛇源代码

嘿嘿 新手来 表现了&#xff01;&#xff01;&#xff01; 2019年结束 游戏截图&#xff1a; 文件布局&#xff1a; 代码分享 用到的一些全局变量 //全局变量 public class Global {public static final int RECT_WIDTH20;//每个小方格的长宽public static final int WIDTH…

AppiumForWin安装

尝试安装Windows版本的Appium参考&#xff1a;http://www.cnblogs.com/fnng/p/4540731.html第一步&#xff1a;安装nodehttps://nodejs.org/en/安装成功后使用&#xff1a;node -v&#xff0c;进行验证第二步&#xff1a;安装Appium下面的方法失败&#xff1a;原因下载不成功&a…

activiti5第一弹-----基本的activiti示例

建立一个普通的javaSE工程&#xff0c;工程的目录结构如下&#xff1a;需要的jar包如下&#xff1a; 在config文件夹下创建log4j.properties用来输入日志&#xff0c;内容如下&#xff1a; log4j.rootLoggerINFO, CA # ConsoleAppender log4j.appender.CAorg.apache.log4j.Cons…

activiti5第三弹-----------脚本任务

首先是流程定义图&#xff1a; 重点关注一下流程节点中 Script Task 节点的 properties中的Main config 这里可以选择不同的脚本语言&#xff0c;由于其他的部怎么会就用javascript来吧。 从图中可以看出只是定义了一个变量x&#xff0c;它的值为 a; 很多人都说这样定义了这个…

activiti5第四弹----serviceTask中的java服务任务

activiti.cfg.xml内容&#xff1a; <?xml version"1.0"?> <beans default-lazy-init"false"xsi:schemaLocation" http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://ww…

activiti5第五弹 serviceTask中的webserviceTask 以及 shellTask

web service task是BPMN2.0中的一种任务类型&#xff0c;在activiti5中它并没有专门的标签表示&#xff0c;而是使用了service task 来表示。而且有很多要配置的内容是无法用图形化工具来完成的。要使用web service task&#xff0c;当然要先有web service。所以首先要编写一个…

activiti5第六弹 手动任务、接收任务、邮件任务

手动任务和接收任务几乎不在程序中做什么事情---只是在流程的历史中留下一点痕迹&#xff0c;表明流程是走过某些节点的。。。而且这两个任务是无法用taskservice查询到的 但是接收任务比手动任务多一个功能&#xff0c;就是确认功能。。。 activiti.cfg.xml配置 <?xml v…

手把手教你用原始方式上传项目至GitHub

小编GitHub&#xff1a;https://github.com/ds1889 首先你得注册一个自己的GitHub账号&#xff0c;注册网址&#xff1a;https://github.com/join 有了自己的账号以后&#xff0c;就可以进行登录&#xff0c;开始创建一个新的项目 创建一个新的项目&#xff0c;填写项目名称&am…

office如何快速删除重复数据

1、首先打开如下文档&#xff0c;在A列删除重复日期星期一&#xff0c;星期二&#xff1b; 2、选中编号栏&#xff0c;&#xff21;1-&#xff21;10&#xff0c;如下图: 3、点击数据——删除重复项&#xff1b;如下图红色剪头所指: 4、删除后&#xff0c;重复项就被删除成功。…

SQL中and和or的区别是?

今天有这样得一个需求&#xff0c;如果登陆人是客服的话&#xff0c;会查询订单是’该客服’以及还没有匹配客服的&#xff0c;刚开始想的是直接在sql语句上拼写 or assigned_id is null 的&#xff0c;测试了一下发现这样的话&#xff0c;前面的其他条件都没有用了 这样的话…