使用jOOQ和JavaFX将SQL数据转换为图表

最近,我们已经展示了Java 8和函数式编程将如何为使用jOOQ和Java 8 lambda和Streams进行SQL数据的函数数据转换为Java开发人员带来新的视角。 今天,我们将这一步骤更进一步,将数据转换为JavaFX XYChart.Series以根据数据生成美观的条形图。

设置数据库

我们将在PostgreSQL数据库中再次使用世界银行开放数据的一小部分。 我们正在使用的数据如下:

DROP SCHEMA IF EXISTS world;CREATE SCHEMA world;CREATE TABLE world.countries (code CHAR(2) NOT NULL,year INT NOT NULL,gdp_per_capita DECIMAL(10, 2) NOT NULL,govt_debt DECIMAL(10, 2) NOT NULL
);INSERT INTO world.countries
VALUES ('CA', 2009, 40764, 51.3),('CA', 2010, 47465, 51.4),('CA', 2011, 51791, 52.5),('CA', 2012, 52409, 53.5),('DE', 2009, 40270, 47.6),('DE', 2010, 40408, 55.5),('DE', 2011, 44355, 55.1),('DE', 2012, 42598, 56.9),('FR', 2009, 40488, 85.0),('FR', 2010, 39448, 89.2),('FR', 2011, 42578, 93.2),('FR', 2012, 39759,103.8),('GB', 2009, 35455,121.3),('GB', 2010, 36573, 85.2),('GB', 2011, 38927, 99.6),('GB', 2012, 38649,103.2),('IT', 2009, 35724,121.3),('IT', 2010, 34673,119.9),('IT', 2011, 36988,113.0),('IT', 2012, 33814,131.1),('JP', 2009, 39473,166.8),('JP', 2010, 43118,174.8),('JP', 2011, 46204,189.5),('JP', 2012, 46548,196.5),('RU', 2009,  8616,  8.7),('RU', 2010, 10710,  9.1),('RU', 2011, 13324,  9.3),('RU', 2012, 14091,  9.4),('US', 2009, 46999, 76.3),('US', 2010, 48358, 85.6),('US', 2011, 49855, 90.1),('US', 2012, 51755, 93.8);

( 另请参阅本文,了解针对上述数据的另一套很棒的SQL查询 )

我们现在要做的是在两个不同的条形图中绘制两组值:

  • 2009-2012年间每个国家的人均GDP
  • 每个国家的债务占其2009年至2012年间每年GDP的百分比

然后,这将创建8个系列,两个图表中的每个系列都有四个数据点。 除上述内容外,我们还希望按2009-2012年之间的平均预测值对系列进行排序,以便可以轻松比较系列-进而比较国家/地区。 显然,通过结果图在视觉上比在文本上更易于解释,因此请保持关注,直到文章结尾。

使用jOOQ和JavaFX收集数据

在普通SQL中,我们为计算上述数据系列而编写的查询如下所示:

select COUNTRIES.YEAR, COUNTRIES.CODE, COUNTRIES.GOVT_DEBT 
from COUNTRIES 
join (select COUNTRIES.CODE, avg(COUNTRIES.GOVT_DEBT) avg from COUNTRIES group by COUNTRIES.CODE
) c1 
on COUNTRIES.CODE = c1.CODE 
order by avg asc, COUNTRIES.CODE asc, COUNTRIES.YEAR asc

换句话说,我们只需要从COUNTRIES表中选择相关列,就可以自动加入每个国家/地区的平均预测值,以便可以按该平均值对结果进行排序。 可以使用窗口函数来编写相同的查询。 我们稍后再讲。

我们将编写以下代码来使用jOOQ和JavaFX创建这样的条形图:

CategoryAxis xAxis = new CategoryAxis();
NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Country");
yAxis.setLabel("% of GDP");BarChart<String, Number> bc = new BarChart<>(xAxis, yAxis);
bc.setTitle("Government Debt");
bc.getData().addAll(// SQL data transformation, executed in the DB// -------------------------------------------DSL.using(connection).select(COUNTRIES.YEAR,COUNTRIES.CODE,COUNTRIES.GOVT_DEBT).from(COUNTRIES).join(table(select(COUNTRIES.CODE, avg(COUNTRIES.GOVT_DEBT).as("avg")).from(COUNTRIES).groupBy(COUNTRIES.CODE)).as("c1")).on(COUNTRIES.CODE.eq(field(name("c1", COUNTRIES.CODE.getName()), String.class)))// order countries by their average // projected value.orderBy(field(name("avg")),COUNTRIES.CODE,COUNTRIES.YEAR)// The result produced by the above statement// looks like this:// +----+----+---------+// |year|code|govt_debt|// +----+----+---------+// |2009|RU  |     8.70|// |2010|RU  |     9.10|// |2011|RU  |     9.30|// |2012|RU  |     9.40|// |2009|CA  |    51.30|// +----+----+---------+// Java data transformation, executed in app memory// ------------------------------------------------// Group results by year, keeping sort // order in place.fetchGroups(COUNTRIES.YEAR)// The generic type of this is inferred...// Stream<Entry<Integer, Result<//     Record3<BigDecimal, String, Integer>>// >>.entrySet().stream()// Map entries into { Year -> Projected value }.map(entry -> new XYChart.Series<>(entry.getKey().toString(),observableArrayList(// Map records into a chart Dataentry.getValue().map(country -> new XYChart.Data<String, Number>(country.getValue(COUNTRIES.CODE),country.getValue(COUNTRIES.GOVT_DEBT)))))).collect(toList())
);

真正有趣的是,我们可以从数据库中获取数据,然后将其一次转换为JavaFX数据结构。 整个过程几乎是一个Java语句。

SQL和Java完全分开

正如我们之前在此博客上所写的那样, 将以上方法与LINQ或JPQL的DTO提取功能进行比较时 ,存在非常重要的区别。 即使我们在一个语句中表示整个转换,SQL查询还是与Java内存数据转换完全分开。

在表达对数据库的SQL查询时,我们希望尽可能精确,以便能够计算最佳执行计划。 只有实现了数据集之后,Java 8 Stream转换才会启动。

当我们将上面的SQL-92兼容查询更改为使用超棒的窗口函数的SQL-1999兼容查询时,这一点的重要性就变得很清楚。 上面的语句的jOOQ部分可以由以下查询代替:

DSL.using(connection).select(COUNTRIES.YEAR,COUNTRIES.CODE,COUNTRIES.GOVT_DEBT).from(COUNTRIES).orderBy(avg(COUNTRIES.GOVT_DEBT).over(partitionBy(COUNTRIES.CODE)),COUNTRIES.CODE,COUNTRIES.YEAR);

…或在SQL中:

selectCOUNTRIES.YEAR,COUNTRIES.CODE,COUNTRIES.GOVT_DEBT
fromCOUNTRIES
order byavg(COUNTRIES.GOVT_DEBT) over (partition by COUNTRIES.CODE),COUNTRIES.CODE,COUNTRIES.YEAR

如您所见,运行此类报告时,至关重要的是要控制实际的SQL语句。 这样,您根本不可能通过窗口函数通过嵌套选择将排序重构为效率更高的排序。 更不用说重构数十行Java排序逻辑了。

是的 难以超越窗口功能之美

如果我们添加一些其他的JavaFX样板文件以将图表放入窗格,场景和舞台中,我们将在下面获得这些漂亮的图表:

带有JavaFX和jOOQ的SQL

带有JavaFX和jOOQ的SQL

自己玩

您可以自己下载并运行上面的示例。 只需下载以下示例并运行mvn clean install : https : //github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/jOOQ-javafx-example

翻译自: https://www.javacodegeeks.com/2015/01/transform-your-sql-data-into-charts-using-jooq-and-javafx.html

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

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

相关文章

node.js学习笔记(1)

一&#xff0e; 安装以及环境配置 安装路径 http://nodejs.cn/download/ 多种环境选择 环境变量的配置 Step1 先检查环境变量中的系统变量里面的path,查看是否加入了node.js 例如我的node.js安装路径是C:\Program Files\nodejs 那么&#xff0c;这个path里面就应该加…

主要版本发布后Java开发人员应使用的15种工具

新部署的生存工具包&#xff1a;适用于Java开发人员的工具&#xff0c;这些工具经常将代码部署到生产中&#xff01; Takipi会检测生产中的所有错误&#xff0c;并像发生错误时一样显示变量值 立即部署并获得免费的T恤 适用于新部署的终极生存套件 与在僵尸末日场景下玩弄&…

Java EE 7批处理和魔兽世界–第2部分

今天&#xff0c;我将把第二部分带到我以前关于Java EE 7批处理和《魔兽世界–第1部分》的帖子中。 在本文中&#xff0c;我们将了解如何从第1部分中获得的数据中汇总和提取指标。 概括 批处理目的是下载魔兽世界拍卖行的数据&#xff0c;处理拍卖并提取指标。 这些指标将建立…

js导航条 二级滑动 模仿块级作用域

for(var i 1;i<7;i){    //因为首级标题有6个&#xff0c;对每个首级标题添加mouseover和mouseout事件。    //这里用到块级作用域(function(k){document.getElementById("p_"k).addEventListener(mouseover,function(event){document.getElementById(p_…

struts+swfupload实现批量图片上传(上):swfupload

custom_settings : {progressTarget : "fsUploadProgress",cancelButtonId : "btnCancel",uploadButtonId : "btnUpload",myFileListTarget : "idFileList" },custom_settings调用方法 this.customSettings.cancelButtonId 缩略图js …

40行中的持久性KeyValue Server和一个可悲的事实

再次出现。. 回顾 Peters关于Unsafe用法的书面概述 &#xff0c;我将简要介绍一下Java中的低级技术如何通过启用更高级别的抽象或允许Java性能级别来节省开发工作可能很多人都不知道。 我的主要观点是表明&#xff0c;将对象转换为字节&#xff0c;反之亦然是一个重要的基础&a…

TreeMap源码分析——深入分析(基于JDK1.6)

TreeMap有Values、EntrySet、KeySet、PrivateEntryIterator、EntryIterator、ValueIterator、KeyIterator、DescendingKeyIterator、NavigableSubMap、AscendingSubMap、DescendingSubMap、SubMap、Entry共十三个内部类。Entry是在TreeMap中用于表示树的节点的内部类&#xff0…

Python2.6 Cx_Oracle Linux下编译安装

分类&#xff1a; python Oracle 2012-06-07 00:04 239人阅读 评论(0) 收藏 举报(一) Python 2.6 安装 1.下载Python2.6.X 版本的源码包&#xff0c;这里采用平台编译安装。 Python-2.6.4.tar.bz2 2.解压缩 ,使用J参数解压bigz2类型的压缩文件 tar -jxvf Python-2.6.4.tar.bz2…

Apache TomEE(和Tomcat)的自签名证书

可能在大多数Java EE项目中&#xff0c;您将拥有具有SSL支持&#xff08; https &#xff09;的部分或整个系统&#xff0c;因此浏览器和服务器可以通过安全连接进行通信。 这意味着在处理数据之前&#xff0c;已发送的数据已加密&#xff0c;传输并最终解密。 问题在于&…

WEB效能测试和负载测试部分截图

效能测试&#xff1a; 负载测试&#xff1a; 转载于:https://www.cnblogs.com/DOOM-scse/archive/2013/01/07/2849110.html

Java8 Lambdas:解释性能缺陷的排序

与Peter Lawrey合作撰写 。 几天前&#xff0c;我对使用新的Java8声明式的排序性能提出了严重的问题。 在这里查看博客文章。 在那篇文章中&#xff0c;我仅指出了问题所在&#xff0c;但在这篇文章中&#xff0c;我将更深入地了解和解释问题的原因。 这将通过使用声明式样式重…

Asp.net MVC3.0 基于不同的角色显示不同的菜单

前面提到过用Asp.net MVC3.0正在做一个问答系统性质的论坛。前期把菜单全部显示以方便测试模块功能。现在正在完善&#xff0c;加上角色模块&#xff0c;然后不同的角色登陆系统会看到不同的菜单栏&#xff0c;还有就是游客&#xff08;未登录用户&#xff09;看到的菜单栏。网…

LoadRunner如何监控Linux下的系统资源

前一段时间在研究LoadRunner过程中&#xff0c;在进行压力场景测试中通过LoadRunner来实时监控windows的系统资源&#xff0c;在前几节中我已经总结了相关过程&#xff0c;近段时间发现群里有朋友问如何监控Linux下的系统资源&#xff0c;所以我也就此问题搭建了一些的Linux环境…

页面跳转多种方法(加传参)

onclick"javascript:location.href/HelpCenter/HelpCenter/" <a href"/HelpCenter/HelpCenter">帮助中心</a>点击页面返回上一页&#xff1a; onclick"javascript:window.history.go(-1); *********************************************…

JCG学院开设了Java设计模式课程!

自从我们推出JCG学院以来&#xff0c;已经有一段时间了。JCG学院是一个基于付费内容的高级订阅网站&#xff0c;提供有关最新技术的课程&#xff0c;涵盖从RedSQL数据库&#xff08;如Redis和CouchDB&#xff09;到使用Android进行移动开发的最新知识。 当然&#xff0c;与Jav…

用友异常清理工具

此类工具网上很多&#xff0c;但&#xff0c;网上的病毒千千万万&#xff0c;还是自己开发使用较为放心。而且具体执行了什么也一清二楚&#xff0c;可以放心。 此工具适用大部份版本&#xff0c;从U821至U871&#xff0c;包括U6系列。 转载于:https://www.cnblogs.com/wuxi15/…

JVM因“ OutOfMemory”错误而关闭-我该怎么办?

看起来似乎很神奇&#xff0c;但是在有关JVM设置的搜索请求结果中经常显示这种“从深度”的呼喊。 您可能会遇到“我记得该选项&#xff0c;但如何启用它”的问题&#xff0c;而有时&#xff08;主要是半年一次&#xff09;管理服务器或调整虚拟设备&#xff0c;而又除主要任务…

JBoss Data Virtualization 6.1 Beta现在可用

JBoss 数据虚拟化 &#xff08;JDV&#xff09;是一种数据集成解决方案&#xff0c;位于多个数据源的前面&#xff0c;并允许将它们视为一个源。 做到这一点&#xff0c;它提供了数据抽象&#xff0c;联合&#xff0c;集成&#xff0c;转换和交付功能&#xff0c;可将来自一个或…

点击显示底框颜色,默认显示第一个。

页面初始化显示第一个底框颜色&#xff0c;点击另一个第一个底框颜色消失&#xff0c;被点击的底框颜色显示&#xff0c;以此循环。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional…

在三个Java IDE中生成的三种常见方法

在本文中&#xff0c;我研究了NetBeans 8.0.2 &#xff0c; IntelliJ IDEA 14.0.2和Eclipse Luna 4.4.1生成的三种“通用”方法[ equals&#xff08;Object&#xff09; &#xff0c; hashCode&#xff08;&#xff09;和toString&#xff08;&#xff09; ]的区别 。 。 目的不…