springbatch读取文件_通过例子讲解Spring Batch入门,优秀的批处理框架
1 前言
“
欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章!
Spring Batch
是一个轻量级的、完善的批处理框架,作为Spring
体系中的一员,它拥有灵活、方便、生产可用的特点。在应对高效处理大量信息、定时处理大量数据等场景十分简便。
结合调度框架能更大地发挥Spring Batch
的作用。
2 Spring Batch的概念知识
2.1 分层架构
Spring Batch
的分层架构图如下:
可以看到它分为三层,分别是:
Application
应用层:包含了所有任务batch jobs
和开发人员自定义的代码,主要是根据项目需要开发的业务流程等。Batch Core
核心层:包含启动和管理任务的运行环境类,如JobLauncher
等。Batch Infrastructure
基础层:上面两层是建立在基础层之上的,包含基础的读入reader
和写出writer
、重试框架等。
2.2 关键概念
理解下图所涉及的概念至关重要,不然很难进行后续开发和问题分析。
2.2.1 JobRepository
专门负责与数据库打交道,对整个批处理的新增、更新、执行进行记录。所以Spring Batch
是需要依赖数据库来管理的。
2.2.2 任务启动器JobLauncher
负责启动任务Job
。
2.2.3 任务Job
Job
是封装整个批处理过程的单位,跑一个批处理任务,就是跑一个Job
所定义的内容。
上图介绍了Job
的一些相关概念:
Job
:封装处理实体,定义过程逻辑。JobInstance
:Job
的运行实例,不同的实例,参数不同,所以定义好一个Job
后可以通过不同参数运行多次。JobParameters
:与JobInstance
相关联的参数。JobExecution
:代表Job
的一次实际执行,可能成功、可能失败。
所以,开发人员要做的事情,就是定义Job
。
2.2.4 步骤Step
Step
是对Job
某个过程的封装,一个Job
可以包含一个或多个Step
,一步步的Step
按特定逻辑执行,才代表Job
执行完成。
通过定义Step
来组装Job
可以更灵活地实现复杂的业务逻辑。
2.2.5 输入——处理——输出
所以,定义一个Job
关键是定义好一个或多个Step
,然后把它们组装好即可。而定义Step
有多种方法,但有一种常用的模型就是输入——处理——输出
,即Item Reader
、Item Processor
和Item Writer
。比如通过Item Reader
从文件输入数据,然后通过Item Processor
进行业务处理和数据转换,最后通过Item Writer
写到数据库中去。
Spring Batch
为我们提供了许多开箱即用的Reader
和Writer
,非常方便。
3 代码实例
理解了基本概念后,就直接通过代码来感受一下吧。整个项目的功能是从多个csv
文件中读数据,处理后输出到一个csv
文件。
3.1 基本框架
添加依赖:
<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-batchartifactId>dependency><dependency> <groupId>com.h2databasegroupId> <artifactId>h2artifactId> <scope>runtimescope>dependency>
需要添加Spring Batch
的依赖,同时使用H2
作为内存数据库比较方便,实际生产肯定是要使用外部的数据库,如Oracle
、PostgreSQL
。
入口主类:
@SpringBootApplication@EnableBatchProcessingpublic class PkslowBatchJobMain { public static void main(String[] args) { SpringApplication.run(PkslowBatchJobMain.class, args); }}
也很简单,只是在Springboot
的基础上添加注解@EnableBatchProcessing
。
领域实体类Employee
:
package com.pkslow.batch.entity;public class Employee { String id; String firstName; String lastName;}
对应的csv
文件内容如下:
id,firstName,lastName1,Lokesh,Gupta2,Amit,Mishra3,Pankaj,Kumar4,David,Miller
3.2 输入——处理——输出
3.2.1 读取ItemReader
因为有多个输入文件,所以定义如下:
@Value("input/inputData*.csv")private Resource[] inputResources;
@Beanpublic MultiResourceItemReader multiResourceItemReader(){ MultiResourceItemReader resourceItemReader = new MultiResourceItemReader(); resourceItemReader.setResources(inputResources); resourceItemReader.setDelegate(reader());return resourceItemReader;}@Beanpublic FlatFileItemReader reader(){ FlatFileItemReader reader = new FlatFileItemReader();//跳过csv文件第一行,为表头 reader.setLinesToSkip(1); reader.setLineMapper(new DefaultLineMapper() { { setLineTokenizer(new DelimitedLineTokenizer() { {//字段名 setNames(new String[] { "id", "firstName", "lastName" }); } }); setFieldSetMapper(new BeanWrapperFieldSetMapper() { {//转换化后的目标类 setTargetType(Employee.class); } }); } });return reader;}
这里使用了FlatFileItemReader
,方便我们从文件读取数据。
3.2.2 处理ItemProcessor
为了简单演示,处理很简单,就是把最后一列转为大写:
public ItemProcessor itemProcessor() { return employee -> { employee.setLastName(employee.getLastName().toUpperCase()); return employee; };}
3.2.3 输出ItremWriter
比较简单,代码及注释如下:
private Resource outputResource = new FileSystemResource("output/outputData.csv");
@Beanpublic FlatFileItemWriter writer(){ FlatFileItemWriter writer = new FlatFileItemWriter<>(); writer.setResource(outputResource);//是否为追加模式 writer.setAppendAllowed(true); writer.setLineAggregator(new DelimitedLineAggregator() { {//设置分割符 setDelimiter(","); setFieldExtractor(new BeanWrapperFieldExtractor() { {//设置字段 setNames(new String[] { "id", "firstName", "lastName" }); } }); } });return writer;}
3.3 Step
有了Reader-Processor-Writer
后,就可以定义Step
了:
@Beanpublic Step csvStep() { return stepBuilderFactory.get("csvStep").chunk(5) .reader(multiResourceItemReader()) .processor(itemProcessor()) .writer(writer()) .build();}
这里有一个chunk
的设置,值为5
,意思是5条记录后再提交输出,可以根据自己需求定义。
3.4 Job
完成了Step
的编码,定义Job
就容易了:
@Beanpublic Job pkslowCsvJob() { return jobBuilderFactory .get("pkslowCsvJob") .incrementer(new RunIdIncrementer()) .start(csvStep()) .build();}
3.5 运行
完成以上编码后,执行程序,结果如下:
成功读取数据,并将最后字段转为大写,并输出到outputData.csv
文件。
4 监听Listener
可以通过Listener
接口对特定事件进行监听,以实现更多业务功能。比如如果处理失败,就记录一条失败日志;处理完成,就通知下游拿数据等。
我们分别对Read
、Process
和Write
事件进行监听,对应分别要实现ItemReadListener
接口、ItemProcessListener
接口和ItemWriteListener
接口。因为代码比较简单,就是打印一下日志,这里只贴出ItemWriteListener
的实现代码:
public class PkslowWriteListener implements ItemWriteListener<Employee> { private static final Log logger = LogFactory.getLog(PkslowWriteListener.class); @Override public void beforeWrite(List extends Employee> list) { logger.info("beforeWrite: " + list); }
@Override public void afterWrite(List extends Employee> list) { logger.info("afterWrite: " + list); }
@Override public void onWriteError(Exception e, List extends Employee> list) { logger.info("onWriteError: " + list); }}
把实现的监听器listener
整合到Step
中去:
@Beanpublic Step csvStep() { return stepBuilderFactory.get("csvStep").chunk(5) .reader(multiResourceItemReader()) .listener(new PkslowReadListener()) .processor(itemProcessor()) .listener(new PkslowProcessListener()) .writer(writer()) .listener(new PkslowWriteListener()) .build();}
执行后看一下日志:
这里就能明显看到之前设置的chunk
的作用了。Writer
每次是处理5条记录,如果一条输出一次,会对IO
造成压力。
5 总结
Spring Batch
还有许多优秀的特性,如面对大量数据时的并行处理。本文主要入门介绍为主,不一一介绍,后续会专门讲解。
欢迎关注微信公众号<南瓜慢说>,将持续为你更新...
多读书,多分享;多写作,多整理。
springbatch读取文件_通过例子讲解Spring Batch入门,优秀的批处理框架相关推荐
- php输出的例子,php 文件读取与读取文件输出内容例子
php读取文件有很多的方法了,我们下文来为各位介绍一些常用的文件读取与输入读取文件内容的例子. 一,读取文件 先解释一下,什么是读取文件本身,什么叫读取文件输入内容.举个例子test.php里面的内容 ...
- java中batch基础_详解Spring batch 入门学习教程(附源码)
详解Spring batch 入门学习教程(附源码) 发布时间:2020-09-08 00:28:40 来源:脚本之家 阅读:99 作者:achuo Spring batch 是一个开源的批处理框架. ...
- springbatch读取文件_Spring Batch读取txt文件并写入数据库的方法教程
项目需求 近日需要实现用户推荐相关的功能,也就是说向用户推荐他可能喜欢的东西. 我们的数据分析工程师会将用户以及用户可能喜欢的东西整理成文档给我,我只需要将数据从文档中读取出来,然后对数据进行进一步的 ...
- spring批量写入mysql数据库_快速使用组件-spring batch(3)读文件数据到数据库
tags: springbatch 1.引言 上一篇文章<快速了解组件-spring batch(2)之helloworld>对Spring Batch进行了入门级的开发,也对基本的组件有 ...
- qt 快速按行读取文件_这是知识点之Linux下分割文件并保留文件头
点击上方"开发者的花花世界",选择"设为星标"技术干货不定时送达! 这是一个知识点 方便快捷的给结构化数据文件分割大小并保留文件的表头,几十个G的结构化文件不仅 ...
- mysql 读取文件_关于mysql:逐行读取文件而不将整个文件加载到内存中
我正在使用50 Gb MySQL导出文件,并对其执行脚本操作列表以转换为SQLite3可加载形式(我从这里得到的线索:脚本将mysql dump sql文件转换为可以导入sqlite3的格式D b ) ...
- java字节流读取文件_字节流读取文件 java的几种IO流读取文件方式
java字节流怎么读取数据 字节流读取数据例子如下: import java.io.File;import java.io.FileInputStream;import java.io.FileNot ...
- jdk8读取文件_用于从文件读取/写入文件的新JDK 11文件方法
jdk8读取文件 我之前的文章重点讨论了可能添加到JDK 11中的Files.isSameContent()方法. JDK-8201276 ["(fs)向文件添加方法以从文件读取字符串或向文 ...
- java使用缓冲区读取文件_在Java中使用Google的协议缓冲区
java使用缓冲区读取文件 最近发布了 有效的Java第三版 ,我一直对确定此类Java开发书籍的更新感兴趣,该书籍的最新版本仅通过Java 6进行了介绍 . 在此版本中,显然存在与Java 7 , ...
最新文章
- ffmpeg + opencv 把摄像头画面保存为mp4文件
- 深入理解 Spring Cloud 核心组件与底层原理!
- ReactNative v0.55学习笔记
- sap 用户权限表_干货丨SAP系统的RPA实施技巧
- 爬虫之拉勾网职位获取
- [python进阶]12.继承的优缺点
- linux安装图像界面
- Silverlight for Windows Phone 7开发系列(1):环境搭建
- 遥感原理与应用_遥感原理与应用考试题库及答案
- 红米6pro刷机教无人直播包教程
- 堆栈宽度学习Stacked BLS的简单python代码实现
- 三洋p6系列伺服电机说明书_苏州发那科伺服电机修理刹不住
- Mac 上“预览”中的键盘快捷键
- 破解电视盒 运营商送的,各种型号。通用 TTL 破解电视盒,更新华为悦盒
- XJOI_3541_开根号
- 使用融云 IM SDK 实现 H5 直播聊天
- 计算机显示器不亮灯,电脑液晶显示器指示灯不亮是为什么?
- 2019.6.14 巴塞尔问题
- Pygame实战:利用Python实现智能五子棋,实现之后发现我玩不赢它。
- 采用京东方屏幕的华为mateX2将难以与三星的折叠手机竞争
热门文章
- 开源软件冲破云霄,“机智号”直升机首飞成功,还带来了第一个火星机场!...
- 首届全国信创大赛圆满收官,信创新势力载誉而归!
- 《CSDN好师父》给你更好选择:“深圳工资、长沙房价、全球视野”
- 微软直播马上开始,近百岗位等你来,快戳进直播间
- 美团推出外卖版拼多多;iOS 14 Beta 3暂禁用3D Touch功能;Rust 1.45 发布| 极客头条
- NB-IoT 连接数过亿,开发者如何抓住新机遇?
- 苹果官网下架 iPhone 8 全系;阿里推出“阿里云会议”;深度操作系统 20 BETA 发布 | 极客头条...
- GitHub 十大顶级 JavaScript 开源项目
- Web 攻击越发复杂,如何保证云上业务高可用性的同时系统不被入侵?| 专家谈...
- 这类程序员,钱包要鼓了!