java spl 是什么_Java 嵌入 SPL 轻松实现数据分组
问题介绍
要在 Java 代码中实现类似 SQL 中的 GroupBy 分组聚合运算,是比较繁琐的,通常先要声明数据结构(Java 实体类),然后用 Java 集合进行循环遍历,最后根据分组条件添加到某个子集合中。Java 8 有了 Lambda(stream)代码简洁了许多,分组后往往还要跟着聚合操作,仍然需要单写聚合函数 sum(),count(*),topN()等。这些还都是最常规的分组和聚合运算,遇到对位分组、枚举分组、多重分组等非常规分组加上其他聚集函数 (FIRST,LAST…),代码就变得非常冗长且不通用。如果能有一个中间件专门负责这类计算,采用类似 SQL 脚本做算法描述,在 Java 中直接调用脚本并返回结果集就好了。Java 版集算器和 SPL 脚本,就是这样的机制,下面举例说明如何使用。
SPL 实现
常规分组
duty.xlsx 文件中保存着每个人的加班记录:
汇总每个人的值班天数:
保存脚本文件CountName.dfx(嵌入 Java 会用到)
每组 TopN
取每个月、每个人、头三天的加班记录
保存脚本文件RecMonTop3.dfx(嵌入 Java 会用到)
Java 调用
SPL 嵌入到 Java 应用程序十分方便,通过 JDBC 调用存储过程方法加载,用常规分组保存的文件CountName.dfx,示例调用如下:
...
Connection con = null;
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
//调用存储过程,其中CountName是dfx的文件名
st =(com. esproc.jdbc.InternalCStatement)con.prepareCall("call CountName()");
//执行存储过程
st.execute();
//获取结果集
ResultSet rs = st.getResultSet();
...
...
Connection con = null;
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
//调用存储过程,其中CountName是dfx的文件名
st =(com. esproc.jdbc.InternalCStatement)con.prepareCall("call CountName()");
//执行存储过程
st.execute();
//获取结果集
ResultSet rs = st.getResultSet();
...
替换成 RecMonTop3.dfx 是同样的道理,只需 call RecMonTop3() 即可,也可同时返回两个结果集。这里只用 Java 片段粗略解释了如何嵌入 SPL,详细步骤请参阅 Java 如何调用 SPL 脚本 ,也非常简单,不再赘述。同时,SPL 也支持 ODBC 驱动,集成到支持 ODBC 的语言,嵌入过程类似。
拓展节选
之前没有相关的总结,其实关于数据分组,细分起来其实还有很多种,对位分组、枚举分组、多重分组…,在乾学院 SPL 官方论坛都有总结和示例,这里节选其中两种。
SPL 对位分组
示例 1:按顺序分别列出使用 Chinese、English、French 作为官方语言的国家数量
MySQL8:
with t(name,ord) as (select 'Chinese',1
union all select 'English',2
union all select 'French',3)
select t.name, count(countrycode) cnt
from t left join world.countrylanguage s on t.name=s.language
where s.isofficial='T'
group by name,ord
order by ord;
MySQL8:
with t(name,ord) as (select 'Chinese',1
union all select 'English',2
union all select 'French',3)
select t.name, count(countrycode) cnt
from t left join world.countrylanguage s on t.name=s.language
where s.isofficial='T'
group by name,ord
order by ord;
注意:表的字符集和数据库会话的字符集要保持一致。
(1) show variables like ’character_set_connection’查看当前会话字符集
(2) show create table world.countrylanguage 查看表的字符集
(3) set character_set_connection=[字符集] 更新当前会话字符集
集算器 SPL:
A1: 连接数据库
A2: 查询出所有官方语言的记录
A3: 需要列出的语言
A4: 将所有记录按 Language 对位到 A3 相应位置
A5: 构造以语言和使用此语言为官方语言的国家数量的序表
示例 2:按顺序分别列出使用 Chinese、English、French 及其它语言作为官方语言的国家数量
MySQL8:
with t(name,ord) as (select 'Chinese',1 union all select 'English',2
union all select 'French',3 union all select 'Other', 4),
s(name, cnt) as (
select language, count(countrycode) cnt
from world.countrylanguage s
where s.isofficial='T' and language in ('Chinese','English','French')
group by language
union all
select 'Other', count(distinct countrycode) cnt
from world.countrylanguage s
where isofficial='T' and language not in ('Chinese','English','French')
)
select t.name, s.cnt
from t left join s using (name)
order by t.ord;
MySQL8:
with t(name,ord) as (select 'Chinese',1 union all select 'English',2
union all select 'French',3 union all select 'Other', 4),
s(name, cnt) as (
select language, count(countrycode) cnt
from world.countrylanguage s
where s.isofficial='T' and language in ('Chinese','English','French')
group by language
union all
select 'Other', count(distinct countrycode) cnt
from world.countrylanguage s
where isofficial='T' and language not in ('Chinese','English','French')
)
select t.name, s.cnt
from t left join s using (name)
order by t.ord;
集算器 SPL:
A4: 将所有记录按 Language 对位到 A3.to(3) 相应位置,并追加一组用于存放不能对位的记录
A5: 第 4 组计算不同 CountryCode 的数量
SPL 枚举分组
示例 1:按顺序列出各类型城市的数量
MySQL8:
with t as (select * from world.city where CountryCode='CHN'),
segment(class,start,end) as (select 'tiny', 0, 200000
union all select 'small', 200000, 1000000
union all select 'medium', 1000000, 2000000
union all select 'big', 2000000, 100000000
)
select class, count(1) cnt
from segment s join t on t.population>=s.start and t.population
group by class, start
order by start;
MySQL8:
with t as (select * from world.city where CountryCode='CHN'),
segment(class,start,end) as (select 'tiny', 0, 200000
union all select 'small', 200000, 1000000
union all select 'medium', 1000000, 2000000
union all select 'big', 2000000, 100000000
)
select class, count(1) cnt
from segment s join t on t.population>=s.start and t.population
group by class, start
order by start;
集算器 SPL:
A3: ${…} 宏替换,以大括号内表达式的结果作为新表达式进行计算,结果为序列 [“?<200000”,“?<1000000”,“?<2000000”,“?<100000000”]
A5: 针对 A2 中每条记录,寻找 A3 中第 1 个成立的条件,并追加到对应的组中
示例 2:列出华东地区大型城市数量、其它地区大型城市数量、非大型城市数量
MySQL8:
with t as (select * from world.city where CountryCode='CHN')
select 'East&Big' class, count(*) cnt
from t
where population>=2000000
and district in ('Shanghai','Jiangshu', 'Shandong','Zhejiang','Anhui','Jiangxi')
union all
select 'Other&Big', count(*)
from t
where population>=2000000
and district not in ('Shanghai','Jiangshu','Shandong','Zhejiang','Anhui','Jiangxi')
union all
select 'Not Big', count(*)
from t
where population<2000000;
MySQL8:
with t as (select * from world.city where CountryCode='CHN')
select 'East&Big' class, count(*) cnt
from t
where population>=2000000
and district in ('Shanghai','Jiangshu', 'Shandong','Zhejiang','Anhui','Jiangxi')
union all
select 'Other&Big', count(*)
from t
where population>=2000000
and district not in ('Shanghai','Jiangshu','Shandong','Zhejiang','Anhui','Jiangxi')
union all
select 'Not Big', count(*)
from t
where population<2000000;
集算器 SPL:
A5: enum@n 将不满足 A4 中所有条件的记录存放到追加的最后一组中
示例 3:列出所有地区大型城市数量、华东地区大型城市数量、非大型城市数量
MySQL8:
with t as (select * from world.city where CountryCode='CHN')
select 'Big' class, count(*) cnt
from t
where population>=2000000
union all
select 'East&Big' class, count(*) cnt
from t
where population>=2000000
and district in ('Shanghai','Jiangshu','Shandong','Zhejiang','Anhui','Jiangxi')
union all
select 'Not Big' class, count(*) cnt
from t
where population<2000000;
MySQL8:
with t as (select * from world.city where CountryCode='CHN')
select 'Big' class, count(*) cnt
from t
where population>=2000000
union all
select 'East&Big' class, count(*) cnt
from t
where population>=2000000
and district in ('Shanghai','Jiangshu','Shandong','Zhejiang','Anhui','Jiangxi')
union all
select 'Not Big' class, count(*) cnt
from t
where population<2000000;
集算器 SPL:
A6: 若 A2 中记录满足 A4 中多个条件时,enum@r 会将其追加到对应的每个组中
优势总结
有库写 SQL,没库写 SPL
用 Java 程序直接汇总计算数据,还是比较累的,代码很长,并且不可复用,很多情况数据也不在数据库里,有了 SPL,就能像在 Java 中用 SQL 一样了,十分方便。
常用无忧,不花钱就能取得终身使用权的入门版
如果要分析的数据是一次性或临时性的,润乾集算器每个月都提供免费试用授权,可以循环免费使用。但要和 Java 应用程序集成起来部署到服务器上长期使用,定期更换试用授权还是比较麻烦,润乾提供了有终身使用权的入门版,解决了这个后顾之忧,获得方式参考 如何免费使用润乾集算器?
技术文档和社区支持
官方提供的集算器技术文档本身就有很多现成的例子,常规问题从文档里都能找到解决方法。如果获得了入门版,不仅能够使用 SPL 的常规功能,碰到任何问题都可以去乾学院上去咨询,官方通过该社区对入门版用户提供免费的技术支持。
java spl 是什么_Java 嵌入 SPL 轻松实现数据分组相关推荐
- excel函数去重_Java 嵌入 SPL 轻松实现 Excel 文件合并
大多数JAVA程序猿都选择使用POI或者HSSFWorkbook等第三方类库来实现Excel自动化合并,这样一来不仅需要噼里啪啦的敲好多代码,费事费力,而且用起来灵活度也不高,对Excel的格式要求也 ...
- Java 嵌入 SPL 轻松实现数据分组
要在 Java 代码中实现类似 SQL 中的 GroupBy 分组聚合运算,是比较繁琐的,通常先要声明数据结构(Java 实体类),然后用 Java 集合进行循环遍历,最后根据分组条件添加到某个子集合 ...
- java excel 展开折叠_Java在Excel中创建多级分组、折叠或展开分组的实现
本文介绍通过java程序在excel创建分组的方法,可对行或列分组进行分组并设置明细数据是否展开或折叠.设置数据分组并展开或折叠时,可通过以下方法: 方法一: 通过方法sheet.groupbyrow ...
- java json解析 代码_Java构造和解析Json数据的两种方法详解一
在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Jso ...
- java中参数存储_Java中函数参数传递和数据存储
值传递是将要传递的值作为一副本传递的.. 引用传递,传递的是引用对象的内存地址.. 例如: int i=4; int j=i; //相当于把4复制了一个副本赋给了j 输出结果是i=4 ,j=4 C ...
- java拆分单元格_Java 拆分Excel单元格数据为多列
一.概述及使用工具 在Excel表格里面,可设置将单元格中的文本数据按分隔符拆分为多列,下面通过Java程序来介绍具体实现方法.这里使用Free Spire.XLS for Java(免费版)来实现数 ...
- java 正则高级应用_JAVA正则表白式高级用法(分组与捉拿).
((A)(B(C)))/A(B(C))(C) 组零始终代表全副表白式 之因而这么命名捉拿组是因为在相称中,保留了与这些组相称的输入序列的每个子序列.捉拿的子序列稍后能够穿越 Back 引用在表白式中利 ...
- java mysql sql注入_Java防SQL注入MySQL数据查询
/** * */ package user.DAO; import java.sql.*; import user.entity.User; /** *//** * 用户数据访问层 * @author ...
- java 返回 json格式_java 如何返回json格式数据,需要技巧
今天上午给同事调了半个小时的程序,最后发现是在后台代码的java返回json格式的数据出了个错误.因此就想到了广大的初学者一开始学习jquery的时候可能会遇到这个问题.现在我就把我的给大家分享一下, ...
最新文章
- HttpClient 如何设置请求接口等待时间
- mysql事务拼写_拼写mysql单词
- ^和$ emeditor
- python3 数组大小_python3从零学习-5.1.8、高效的数值数组array
- 茫茫内存,我该如何用 windbg 找到你 ?
- java.sql 拒绝连接_hive jdbc 拒绝连接问题
- 资源丨MySQL故障排查思路方法PPT视频24问答
- 【JMX】JMX 远程 连接 The client has been closed
- 中国团队屠榜:COCOMapillary挑战赛包揽全部冠军
- 8086可以用c语言编程吗,[求助]如何将C程序反汇编成8086汇编程序
- pxe dhcp offer之后没有_秒懂DHCP是什么
- linux目录与文件,Linux目录与文件基本操作
- 平面直角坐标系中的旋转公式_难点解析丨空间直线、平面平行的判定及其性质...
- 传统企业如何精准获客?搭上这趟高科技顺风车
- 关于投资有哪些不得不读的书籍?
- 永远不怕IE主页地址被修改
- java期未项目_Java项目实战知到期末答案
- 微信开发修改button里的字体大小_在微信小程序中如何修改文字大小
- CMS简数采集数据发布到迅睿CMS教程
- 自动驾驶(七)---------初探轨迹规划
热门文章
- [转载]Android wifi探究一:初步认识wpa_supplicant与wifi框架梳理
- PullToRefresh使用详解(一)--构建下拉刷新的listView
- 有品css进度12.6
- Python 二分查找与方程求解(公开代码)
- x86汇编 linux,Linux操作系统的X86汇编程序设计
- html5怎么让图片在导航栏后,请问前端大神,html如何引入另一个html,写了一个导航栏想在多个页面中如何重复使用?...
- EEPROM读写实验
- 为什么hashcode的算法要用31作为乘子
- QT自制TCP客户端
- STM32通过串口进入和唤醒停止模式