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

今天,我将把第二部分带到我以前关于Java EE 7批处理和《魔兽世界–第1部分》的帖子中。 在本文中,我们将了解如何从第1部分中获得的数据中汇总和提取指标。

orgrimmar拍卖行

概括

批处理目的是下载魔兽世界拍卖行的数据,处理拍卖并提取指标。 这些指标将建立拍卖项目价格随时间变化的历史记录。 在第1部分中 ,我们已经下载了数据并将其插入数据库。

应用程序

处理作业

在将原始数据添加到数据库之后,我们将添加一个带有Chunk样式处理的步骤。 在块中,我们将读取聚合的数据,然后将其插入数据库中的另一个表中以便于访问。 这是在process-job.xml

process-job.xml

<step id="importStatistics"><chunk item-count="100"><reader ref="processedAuctionsReader"/><processor ref="processedAuctionsProcessor"/><writer ref="processedAuctionsWriter"/></chunk>
</step>

块一次读取一个数据,并在事务内创建要写出的块。 从ItemReader读入一项,交给ItemProcessor并进行聚合。 一旦读取的项目数等于提交间隔,就通过ItemWriter写入整个块,然后提交事务。

ProcessedAuctionsReader

在读者中,我们将使用数据库功能选择和汇总指标。

ProcessedAuctionsReader.java

@Named
public class ProcessedAuctionsReader extends AbstractAuctionFileProcess implements ItemReader {@Resource(name = "java:comp/DefaultDataSource")protected DataSource dataSource;private PreparedStatement preparedStatement;private ResultSet resultSet;@Overridepublic void open(Serializable checkpoint) throws Exception {Connection connection = dataSource.getConnection();preparedStatement = connection.prepareStatement("SELECT" +"   itemid as itemId," +"   sum(quantity)," +"   sum(bid)," +"   sum(buyout)," +"   min(bid / quantity)," +"   min(buyout / quantity)," +"   max(bid / quantity)," +"   max(buyout / quantity)" +" FROM auction" +" WHERE auctionfile_id = " +getContext().getFileToProcess().getId() +" GROUP BY itemid" +" ORDER BY 1",ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY,ResultSet.HOLD_CURSORS_OVER_COMMIT);// Weird bug here. Check https://java.net/bugzilla/show_bug.cgi?id=5315//preparedStatement.setLong(1, getContext().getFileToProcess().getId());resultSet = preparedStatement.executeQuery();}@Overridepublic void close() throws Exception {DbUtils.closeQuietly(resultSet);DbUtils.closeQuietly(preparedStatement);}@Overridepublic Object readItem() throws Exception {return resultSet.next() ? resultSet : null;}@Overridepublic Serializable checkpointInfo() throws Exception {return null;}

在此示例中,我们通过使用具有简单可滚动结果集的纯JDBC获得最佳性能结果。 这样,仅执行一个查询,并根据需要在readItem中提取结果。 您可能想探索其他替代方法。

Plain JPA在标准中没有可滚动的结果集,因此您需要对结果进行分页。 这将导致多个查询,这将减慢阅读速度。 另一个选择是使用新的Java 8 Streams API来执行聚合操作。 这些操作很快,但是您需要从数据库中选择整个数据集到流中。 最终,这会削弱您的性能。

我确实尝试了这两种方法,并通过使用数据库聚合功能获得了最佳结果。 我并不是说这始终是最好的选择,但是在这种情况下,这是最好的选择。

在实施过程中,我还发现了Batch中的错误。 您可以在这里检查。 在PreparedStatement中设置参数时会引发异常。 解决方法是将参数直接注入查询SQL中。 丑陋,我知道...

ProcessedAuctionsProcessor

在处理器中,让我们将所有聚合值存储在一个holder对象中,以存储在数据库中。

ProcessedAuctionsProcessor.java

@Named
public class ProcessedAuctionsProcessor extends AbstractAuctionFileProcess implements ItemProcessor {@Override@SuppressWarnings("unchecked")public Object processItem(Object item) throws Exception {ResultSet resultSet = (ResultSet) item;AuctionItemStatistics auctionItemStatistics = new AuctionItemStatistics();auctionItemStatistics.setItemId(resultSet.getInt(1));auctionItemStatistics.setQuantity(resultSet.getLong(2));auctionItemStatistics.setBid(resultSet.getLong(3));auctionItemStatistics.setBuyout(resultSet.getLong(4));auctionItemStatistics.setMinBid(resultSet.getLong(5));auctionItemStatistics.setMinBuyout(resultSet.getLong(6));auctionItemStatistics.setMaxBid(resultSet.getLong(7));auctionItemStatistics.setMaxBuyout(resultSet.getLong(8));auctionItemStatistics.setTimestamp(getContext().getFileToProcess().getLastModified());auctionItemStatistics.setAvgBid((double) (auctionItemStatistics.getBid() / auctionItemStatistics.getQuantity()));auctionItemStatistics.setAvgBuyout((double) (auctionItemStatistics.getBuyout() / auctionItemStatistics.getQuantity()));auctionItemStatistics.setRealm(getContext().getRealm());return auctionItemStatistics;}
}

由于指标会及时记录数据的准确快照,因此计算仅需执行一次。 这就是为什么我们要保存汇总指标。 它们永远不会改变,我们可以轻松地检查历史。

如果您知道源数据是不可变的,并且需要对其进行操作,那么建议您将结果保留在某处。 这样可以节省您的时间。 当然,如果将来要多次访问此数据,则需要平衡。 如果不是这样,也许您就不需要经历持久化数据的麻烦了。

ProcessedAuctionsWriter

最后,我们只需要将数据写到数据库中即可:

ProcessedAuctionsWriter.java

@Named
public class ProcessedAuctionsWriter extends AbstractItemWriter {@PersistenceContextprotected EntityManager em;@Override@SuppressWarnings("unchecked")public void writeItems(List items) throws Exception {List<AuctionItemStatistics> statistis = (List<AuctionItemStatistics>) items;statistis.forEach(em::persist);}
}

指标

现在,为了对数据做一些有用的事情,我们将公开一个REST端点,以对所计算的指标执行查询。 方法如下:

WowBusinessBean.java

@Override @GET@Path("items")public List<AuctionItemStatistics> findAuctionItemStatisticsByRealmAndItem(@QueryParam("realmId") Long realmId,@QueryParam("itemId") Integer itemId) {Realm realm = (Realm) em.createNamedQuery("Realm.findRealmsWithConnectionsById").setParameter("id", realmId).getSingleResult();// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=433075 if using EclipseLinkList<Realm> connectedRealms = new ArrayList<>();connectedRealms.addAll(realm.getConnectedRealms());List<Long> ids = connectedRealms.stream().map(Realm::getId).collect(Collectors.toList());ids.add(realmId);return em.createNamedQuery("AuctionItemStatistics.findByRealmsAndItem").setParameter("realmIds", ids).setParameter("itemId", itemId).getResultList();}

如果您还记得第1部分中的一些细节,那么魔兽世界服务器称为Realms 。 这些领域可以相互链接并共享同一拍卖行 。 为此,我们还拥有有关领域之间如何相互联系的信息。 这很重要,因为我们可以在所有连接的领域中搜索拍卖品 。 其余的逻辑只是简单的查询以获取数据。

在开发过程中,我还发现了Eclipse Link (如果您在Glassfish中运行)和Java 8的错误。显然, Eclipse Link返回的基础Collection的元素计数设置为0。尝试内联查询调用以及Stream操作。 流将认为它为空,并且不会返回任何结果。 您可以在这里有关此的内容。

接口

我还使用Angular和Google Charts开发了一个小界面来显示指标。 看一看:

哇拍卖

在这里,我在寻找一个名为“Aggra(葡萄牙语)”的境界拍卖项目编号72092对应于鬼铁矿石 。 如您所见,我们可以检查待售数量,出价和买断值以及价格随时间的波动。 整齐? 我可能会写另一篇关于将来构建Web Interface的文章。

资源资源

您可以从我的github存储库中克隆完整的工作副本,然后将其部署到Wildfly或Glassfish中 。 您可以在那里找到部署说明: 魔兽世界拍卖

也请检查Java EE示例项目,其中包含大量完整的批处理示例。

翻译自: https://www.javacodegeeks.com/2015/01/java-ee-7-batch-processing-and-world-of-warcraft-part-2.html

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

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

相关文章

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; ]的区别 。 。 目的不…

angularjs 利用filter进行表单查询及分页查询

页面&#xff1a; <div><input style"width:90%;margin-left:5px;margin-right:5px;" class"form-control sys_input" ng-model"imagePaths.filter.imageName" placeholder"查询..."/></div><div><!--<…

为什么现在是升级到Java 8的最佳时机

有兴趣了解如何通过AppDynamics充分利用Java 8的新功能吗&#xff1f; 立即开始免费试用 &#xff01; 今年3月&#xff0c;Oracle发布了近十年来最受期待的版本Java8。自发布以来&#xff0c;最新版本引起了越来越多的关注&#xff0c;各种规模的公司都渴望升级。 我们的合作…

requirejs与anjularjs框架

1.目录 2.首页login.html如下&#xff1a; <!DOCTYPE html><html> <head> <title>登录界面</title> <link relstylesheet href/stylesheets/style.css /> <link rel"stylesheet" href"/css/bootstrap.min.css">…