这里我们对springbatch做一个比较深入的学习例子,解压文件,读取文件内容过滤写入到数据库中。如果你掉进了黑暗里,你能做的,不过是静心等待,直到你的双眼适应黑暗。

springbatch的使用案例

  首先,我们来列举一下spring batch里面所涉及到的概念。

1、Job repository
An infrastructure component that persists job execution metadata
2、Job launcher
An infrastructure component that starts job executions
3、Job
An application component that represents a batch process
4、Step
A phase in a job; a job is a sequence of steps
5、Tasklet
A transactional, potentially repeatable process occurring in a step
6、Item
A record read from or written to a data source
7、Chunk
A list of items of a given size
8、Item reader
A component responsible for reading items from a data source
9、Item processor
A component responsible for processing (transforming, validating, or filtering) a read item before it’s written
10、Item writer
A component responsible for writing a chunk to a data source

   我们的项目是基于上篇博客的,具体的可以参考博客:springbatch---->springbatch的使用(一)。流程:将得到的zip文件解压成txt文件,根据里面的信息。我们过滤到年龄大于30的数据,并把过滤后的数据按格式存放到数据库中。以下我们只列出新增或者修改的文件内容。

一、关于xml文件的修改,增加一个job.xml文件和修改batch.xml文件

  • batch.xml文件增加内容:
<!-- 读取文件写入到数据库的job -->
<job id="readFlatFileJob">
<step id="decompress" next="readWriter">
<tasklet ref="decompressTasklet"/>
</step>
<step id="readWriter" next="clean">
<tasklet>
<chunk reader="reader" writer="writer" commit-interval="100" processor="processor"/>
</tasklet>
</step>
<step id="clean">
<tasklet ref="cleanTasklet"/>
</step>
</job>

  关于commit-interval:Number of items to process before issuing a commit. When the number of items read reaches the commit interval number, the entire corresponding chunk is written out through the item writer and the transaction is committed.

  • 新增的job.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 对压缩文件进行解压 -->
<bean id="decompressTasklet" class="spring.batch.readFile.DecompressTasklet">
<property name="inputResource" value="file:file/file.zip"/>
<property name="targetDirectory" value="file"/>
<property name="targetFile" value="file.txt"/>
</bean> <!-- 读取文本文件 -->
<bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="lineMapper" ref="lineMapper"/>
<property name="linesToSkip" value="1"/> <!-- 跳过第一行,也就是从第二行开始读 -->
<property name="resource" value="file:file/file.txt"/>
</bean> <!-- 对读取的内容做过滤处理 -->
<bean id="processor" class="spring.batch.readFile.FileProcessor"/> <!-- 将读取的内容写到数据库中 -->
<bean id="writer" class="spring.batch.readFile.FileWriter">
<constructor-arg ref="dataSource"/>
</bean> <!-- 清除压缩文件-->
<bean id="cleanTasklet" class="spring.batch.readFile.FileCleanTasklet">
<property name="resource" value="file:file/file.zip"/>
</bean> <!-- 对文件里面的数据进行|分割,映射成一个类 -->
<bean id="lineMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer" ref="delimitedLineTokenizer"/>
<property name="fieldSetMapper">
<bean class="spring.batch.readFile.ReadFileMapper"/>
</property>
</bean>
<bean id="delimitedLineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<constructor-arg name="delimiter" value="|"/>
</bean> <!-- 简单的数据源配置 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/csiilearn"/>
<property name="username" value="root"/>
<property name="password" value="*****"/>
</bean>
</beans>

其实关于有格式的文件的读写,springbatch为我们提供了FlatFileItemWriter和FlatFileItemReader类。我们可以直接使用,只需要配置它的属性就行。

二、新增加的java类,如下所示

  • DecompressTasklet:对zip文件进行解压
package spring.batch.readFile;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.core.io.Resource; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.zip.ZipInputStream; /**
* @Author: huhx
* @Date: 2017-11-01 上午 9:39
*/
public class DecompressTasklet implements Tasklet {
private Resource inputResource;
private String targetDirectory;
private String targetFile; @Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("file path: " + inputResource.getFile().getAbsolutePath());
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(
inputResource.getInputStream()));
File targetDirectoryAsFile = new File(targetDirectory);
if (!targetDirectoryAsFile.exists()) {
FileUtils.forceMkdir(targetDirectoryAsFile);
}
File target = new File(targetDirectory, targetFile);
BufferedOutputStream dest = null;
while (zis.getNextEntry() != null) {
if (!target.exists()) {
target.createNewFile();
}
FileOutputStream fos = new FileOutputStream(target);
dest = new BufferedOutputStream(fos);
IOUtils.copy(zis, dest);
dest.flush();
dest.close();
}
zis.close();
if (!target.exists()) {
throw new IllegalStateException("Could not decompress anything from the archive!");
}
return RepeatStatus.FINISHED;
} public void setInputResource(Resource inputResource) {
this.inputResource = inputResource;
} public void setTargetDirectory(String targetDirectory) {
this.targetDirectory = targetDirectory;
} public void setTargetFile(String targetFile) {
this.targetFile = targetFile;
}
}
  • People:数据库映射的javaBean类
public class People implements Serializable {
private String username;
private int age;
private String address;
private Date birthday; ..get...set...
}
  • ReadFileMapper:读取文件字段的映射
package spring.batch.readFile;

import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.validation.BindException; /**
* @Author: huhx
* @Date: 2017-11-01 上午 10:11
*/
public class ReadFileMapper implements FieldSetMapper<People> { @Override
public People mapFieldSet(FieldSet fieldSet) throws BindException {
People people = new People();
people.setUsername(fieldSet.readString(0));
people.setAge(fieldSet.readInt(1));
people.setAddress(fieldSet.readString(2));
people.setBirthday(fieldSet.readDate(3));
return people;
}
}
  • FileProcessor:对读取的数据做进一步的处理,这里我们是过滤操作
package spring.batch.readFile;

import org.springframework.batch.item.ItemProcessor;

/**
* @Author: huhx
* @Date: 2017-11-01 上午 9:43
*/
public class FileProcessor implements ItemProcessor<People, People> {
@Override
public People process(People item) throws Exception {
return needsToBeFiltered(item) ? null : item;
} private boolean needsToBeFiltered(People item) {
int age = item.getAge();
return age > 30 ? true : false;
}
}
  • FileWriter:对最终过滤后的数据写入数据库中
package spring.batch.readFile;

import org.springframework.batch.item.ItemWriter;
import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource;
import java.util.List; /**
* @Author: huhx
* @Date: 2017-11-01 上午 9:42
*/
public class FileWriter implements ItemWriter<People> {
private static final String INSERT_PRODUCT = "INSERT INTO batch_user (user_name, age, address, birthday) VALUES(?, ?, ?, ?)"; private JdbcTemplate jdbcTemplate; public FileWriter(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
} @Override
public void write(List<? extends People> items) throws Exception {
for (People people : items) {
jdbcTemplate.update(INSERT_PRODUCT, people.getUsername(), people.getAge(), people.getAddress(), people.getBirthday());
}
}
}
  • FileCleanTasklet:做流程最后的清理处理,删除zip文件
package spring.batch.readFile;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.core.io.Resource; import java.io.File; /**
* @Author: huhx
* @Date: 2017-11-01 上午 9:44
*/
public class FileCleanTasklet implements Tasklet {
private Resource resource; public void setResource(Resource resource) {
this.resource = resource;
} @Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
File file = resource.getFile();
file.deleteOnExit();
return RepeatStatus.FINISHED;
}
}

三、修改JobLaunch.java文件里面的内容

Job job = (Job) context.getBean("readFlatFileJob");
  • zip解压后的文件内容:
姓名|年龄|地址|生日
李元芳||黄冈|--
王昭君||武汉|--
狄仁杰||天津|--
孙悟空||黄冈|--
牛魔王||武汉|--
孙尚香||天津|--
  • 运行后的数据库batch_user表的数据:

友情链接

springbatch---->springbatch的使用(二)的更多相关文章

  1. SpringBatch Sample (二)(CSV文件操作)

    本文将通过一个完整的实例,与大家一起讨论运用Spring Batch对CSV文件的读写操作.此实例的流程是:读取一个含有四个字段的CSV文件(ID,Name,Age,Score),对读取的字段做简单的 ...

  2. YII内置验证规则

    required: 必填字段验证, 来自 CRequiredValidator类的别名 array(‘字段名列表用逗号隔开’, ‘required’),    就这样的一个小小的写法,可以让字段前面加 ...

  3. Spring Batch介绍

    简介 SpringBatch 是一个大数据量的并行处理框架.通常用于数据的离线迁移,和数据处理,⽀持事务.并发.流程.监控.纵向和横向扩展,提供统⼀的接⼝管理和任务管理;SpringBatch是Spr ...

  4. springbatch操作CSV文件

    一.需求分析 使用Spring Batch对CSV文件进行读写操作: 读取一个含有四个字段的CSV文件(id, name, age, score), 对文件做简单的处理, 然后输出到还有一个csv文件 ...

  5. SpringBatch的初步了解

    一.SpringBatch是一个批处理的框架,作为一个Spring组件,提供了通过使用Spring的依赖注入来处理批处理的条件. 什么是批处理呢? 在现代企业应用当中,面对复杂的业务以及海量的数据,除 ...

  6. springbatch操作DB

    一.需求分析 使用Spring Batch对DB进行读写操作: 从一个表中读取数据, 然后批量的插入另外一张表中. 二.代码实现 1. 代码结构图: 2. applicationContext.xml ...

  7. SpringBoot整合SpringBatch

    一.引入依赖 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&q ...

  8. SpringBatch的核心组件JobLauncher和JobRepository

    Spring Batch的框架包括启动批处理作业的组件和存储Job执行产生的元数据.因此只需掌握配置这个基础框架在批处理应用程序中即启动Jobs并存储Job元数据. 组件:Job Launcher和J ...

  9. SpringBatch简介

    spring Batch是一个轻量级的.完善的批处理框架,旨在帮助企业建立健壮.高效的批处理应用.SpringBatch是Spring的一个子项目,使用Java语言并基于Spring框架为基础开发,使 ...

  10. spring-boot-oracle spring-batch

    Install/Configure Oracle express Oracle xe installer for linux (I don't care if you're running linux ...

随机推荐

  1. jQuery Validation让验证变得如此easy(二)

    上一个样例我们是统一引用jquery.validate.js这样全部必填字段的提示信息都将是This field is required. 如今要改成动态提示,比方姓名假设为空则提示姓名不能为空,密码 ...

  2. POI写docx文件table中的单元格水平、垂直对齐

    核心示例代码 垂直对齐 XWPFTableCell cell = table.getRow(i).getCell(j); cell.setVerticalAlignment(XWPFTableCell ...

  3. 联想服务器RD450 配置RAID5

    实验环境: 1.服务器型号 ThinkServer RD450 2.四块1TB普通SATA硬盘 实验目的: 配置RAID 5 ,搭建公司文件共享服务器使用. 标注:本教程四块硬盘全做RAID 5,如果 ...

  4. css 垂直居中,指定文本宽度换行,指定高度出滚动条

    !DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"&g ...

  5. Thinkphp5 多图上传

    html代码 <div class="content" id="content_list"> <!-- 上传部分 --> <for ...

  6. UNIX环境编程学习笔记(4)——文件I/O之dup复制文件描述符

    lienhua342014-08-23 UNIX 提供了两个函数 dup 和 dup2 用于复制一个现存的文件描述符. #include <unistd.h> int dup(int fi ...

  7. 内存管理 初始化(四)mem_init bootmem 迁移至伙伴系统

    mm_init中执行mem_init,将原通过bootmem分配器管理的低端内存 及  通过meminfo得知的高端内存释放到伙伴系统中,最后bootmem位图本身占用的低端内存物理页也被释放进伙伴系 ...

  8. python内存泄漏,python垃圾手动回收,1

    部署的舆情系统,内存变大,找原因. 一个小例子. def func(): local_list = list(range(10000000)) func() time.sleep(200) 能够观察到 ...

  9. [scala] scala 对象(六)

    1.单例对象和伴生对象 2.定义单利对象的apply方法可不通过构造器直接创建对象 3.extends 来扩展单例对象 4.枚举实现 /** * 单例对象 * * @author xuejz * @d ...

  10. winform 打开一个窗体,关闭一个窗体

    例如  我要打开一个窗体b,关闭一个窗体a a中的代码添加: private void pictureBox5_Click(object sender, EventArgs e) { W_MainFo ...