歡迎來到 Spring Batch 示例. Spring Batch 是一個 spring framework模塊,用於執行批次工作。
春节 例子
在通过春分示例程序之前,让我们了解一下 [春分配]( / 社区 / 教程 / 春分配)术语。
一个任务可以由n
数量的步骤组成,每个步骤都包含 阅读过程编写任务,或者它可以有一个单个操作,称为tasklet
*阅读过程编写基本上是从数据库,CSV等源读取的,然后处理数据,并将其写入数据库,CSV,XML等源
*任务编写意味着执行单个任务或操作,如清理连接,在处理完成后释放资源
*阅读过程编写和任务编写可以连接在一起执行任务
春节 例子
我们将考虑下面的场景来实现目的. 包含数据需要转换为 XML 的 CSV 文件以及数据和标签将在列名后命名。
- Apache Maven 3.5.0 - 用于项目构建和依赖管理
- Eclipse Oxygen 发布 4.7.0 - 用于创建春季批量maven应用程序的 IDE
- Java 1.8
- 春季核心 4.3.12.RELEASE
- 春季 OXM 4.3.12.RELEASE
- 春季 JDBC 4.3.12.RELEASE
- 春季批量 3.0.8.RELEASE
- MySQL Java 驱动程序 5.1.25 - 基于您的MySQL 安装。 这是春季批量元数据表
Spring Batch 示例目录结构
Below image illustrates all the components in our Spring Batch example project.
春天大麻依赖性
下面是 pom.xml 文件的内容,包括我们春季批量示例项目所需的所有依赖。
1<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
3 <modelVersion>4.0.0</modelVersion>
4
5 <groupId>com.journaldev.spring</groupId>
6 <artifactId>SpringBatchExample</artifactId>
7 <version>0.0.1-SNAPSHOT</version>
8 <packaging>jar</packaging>
9
10 <name>SpringBatchDemo</name>
11 <url>https://maven.apache.org</url>
12
13 <properties>
14 <jdk.version>1.8</jdk.version>
15 <spring.version>4.3.12.RELEASE</spring.version>
16 <spring.batch.version>3.0.8.RELEASE</spring.batch.version>
17 <mysql.driver.version>5.1.25</mysql.driver.version>
18 <junit.version>4.11</junit.version>
19 </properties>
20
21 <dependencies>
22
23 <!-- Spring Core -->
24 <dependency>
25 <groupId>org.springframework</groupId>
26 <artifactId>spring-core</artifactId>
27 <version>${spring.version}</version>
28 </dependency>
29
30 <!-- Spring jdbc, for database -->
31 <dependency>
32 <groupId>org.springframework</groupId>
33 <artifactId>spring-jdbc</artifactId>
34 <version>${spring.version}</version>
35 </dependency>
36
37 <!-- Spring XML to/back object -->
38 <dependency>
39 <groupId>org.springframework</groupId>
40 <artifactId>spring-oxm</artifactId>
41 <version>${spring.version}</version>
42 </dependency>
43
44 <!-- MySQL database driver -->
45 <dependency>
46 <groupId>mysql</groupId>
47 <artifactId>mysql-connector-java</artifactId>
48 <version>${mysql.driver.version}</version>
49 </dependency>
50
51 <!-- Spring Batch dependencies -->
52 <dependency>
53 <groupId>org.springframework.batch</groupId>
54 <artifactId>spring-batch-core</artifactId>
55 <version>${spring.batch.version}</version>
56 </dependency>
57 <dependency>
58 <groupId>org.springframework.batch</groupId>
59 <artifactId>spring-batch-infrastructure</artifactId>
60 <version>${spring.batch.version}</version>
61 </dependency>
62
63 <!-- Spring Batch unit test -->
64 <dependency>
65 <groupId>org.springframework.batch</groupId>
66 <artifactId>spring-batch-test</artifactId>
67 <version>${spring.batch.version}</version>
68 </dependency>
69
70 <!-- Junit -->
71 <dependency>
72 <groupId>junit</groupId>
73 <artifactId>junit</artifactId>
74 <version>${junit.version}</version>
75 <scope>test</scope>
76 </dependency>
77
78 <dependency>
79 <groupId>com.thoughtworks.xstream</groupId>
80 <artifactId>xstream</artifactId>
81 <version>1.4.10</version>
82 </dependency>
83
84 </dependencies>
85 <build>
86 <finalName>spring-batch</finalName>
87 <plugins>
88 <plugin>
89 <groupId>org.apache.maven.plugins</groupId>
90 <artifactId>maven-eclipse-plugin</artifactId>
91 <version>2.9</version>
92 <configuration>
93 <downloadSources>true</downloadSources>
94 <downloadJavadocs>false</downloadJavadocs>
95 </configuration>
96 </plugin>
97 <plugin>
98 <groupId>org.apache.maven.plugins</groupId>
99 <artifactId>maven-compiler-plugin</artifactId>
100 <version>2.3.2</version>
101 <configuration>
102 <source>${jdk.version}</source>
103 <target>${jdk.version}</target>
104 </configuration>
105 </plugin>
106 </plugins>
107 </build>
108</project>
春季批量处理 CSV 输入文件
以下是我们春季批量加工样本CSV文件的内容。
11001,Tom,Moody, 29/7/2013
21002,John,Parker, 30/7/2013
31003,Henry,Williams, 31/7/2013
春季批量工作配置
我們必須在配置檔案中定義 spring bean和 Spring batch job. 下面是 job-batch-demo.xml
檔案的內容,它是 Spring batch 項目中最重要的部分。
1<beans xmlns="https://www.springframework.org/schema/beans"
2 xmlns:batch="https://www.springframework.org/schema/batch" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="https://www.springframework.org/schema/batch
4 https://www.springframework.org/schema/batch/spring-batch-3.0.xsd
5 https://www.springframework.org/schema/beans
6 https://www.springframework.org/schema/beans/spring-beans-4.3.xsd
7 ">
8
9 <import resource="../config/context.xml" />
10 <import resource="../config/database.xml" />
11
12 <bean id="report" class="com.journaldev.spring.model.Report"
13 scope="prototype" />
14 <bean id="itemProcessor" class="com.journaldev.spring.CustomItemProcessor" />
15
16 <batch:job id="DemoJobXMLWriter">
17 <batch:step id="step1">
18 <batch:tasklet>
19 <batch:chunk reader="csvFileItemReader" writer="xmlItemWriter"
20 processor="itemProcessor" commit-interval="10">
21 </batch:chunk>
22 </batch:tasklet>
23 </batch:step>
24 </batch:job>
25
26 <bean id="csvFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
27
28 <property name="resource" value="classpath:csv/input/report.csv" />
29
30 <property name="lineMapper">
31 <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
32 <property name="lineTokenizer">
33 <bean
34 class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
35 <property name="names" value="id,firstname,lastname,dob" />
36 </bean>
37 </property>
38 <property name="fieldSetMapper">
39 <bean class="com.journaldev.spring.ReportFieldSetMapper" />
40
41 <!-- if no data type conversion, use BeanWrapperFieldSetMapper to map
42 by name <bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
43 <property name="prototypeBeanName" value="report" /> </bean> -->
44 </property>
45 </bean>
46 </property>
47
48 </bean>
49
50 <bean id="xmlItemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
51 <property name="resource" value="file:xml/outputs/report.xml" />
52 <property name="marshaller" ref="reportMarshaller" />
53 <property name="rootTagName" value="report" />
54 </bean>
55
56 <bean id="reportMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
57 <property name="classesToBeBound">
58 <list>
59 <value>com.journaldev.spring.model.Report</value>
60 </list>
61 </property>
62 </bean>
63
64</beans>
- 联合国 我们正在使用
FlatFile项目Reader'读取CSV文件
海关项目处理器',使用StaxEvent项目Writer'处理数据并写入XML文件。 (_) )2.
批:工作 ' - 此标签定义了我们要创建的工作 。 ID 属性指定工作身份 。 我们可以在一个xml文件中定义多个任务. (_) )3. 批:分步骤- 此标签用于定义弹簧批量任务的不同步骤. - 由"Spring Batch Framework"提供两种不同类型的处理风格,分别是"任务定位"和"Chunk Oriented". 此示例中使用的Chunk Oriented样式是指在交易边界内逐一读取数据并创建将写入的"chunks". (_)
- 阅读器:用于读取数据的春豆. 我们在此例子中使用了
csvFile项目阅读器'豆,即
FlatFile项目阅读器'的例子。 () )6. 处理器:这是用于处理数据的类. 我们在此例子中使用了`海关项目处理器'。 () - 编剧:用豆子将数据写入xml文件. (_) (英语). 8. 承诺间断 : 此属性定义了处理完成后将执行的块大小 。 基本上,这意味着项目阅读器将逐一读取数据,项目处理器也将以同样的方式处理数据,但项目Writer只有在等同承诺间距大小时才会写入数据.
- 作为该项目一部分使用的三个主要接口是
项目阅读器 ' 、
项目处理器 ' 和项目Writer ' 从
org.springframework.batch.trome'软件包。 (_) (英语)
春季班级模型
首先,我们正在阅读 CSV 文件到 java 对象,然后使用 [JAXB]( / 社区 / 教程 / jaxb 示例 - 教程)将其写入 xml 文件。
1package com.journaldev.spring.model;
2
3import java.util.Date;
4
5import javax.xml.bind.annotation.XmlAttribute;
6import javax.xml.bind.annotation.XmlElement;
7import javax.xml.bind.annotation.XmlRootElement;
8
9@XmlRootElement(name = "record")
10public class Report {
11
12 private int id;
13 private String firstName;
14 private String lastName;
15 private Date dob;
16
17 @XmlAttribute(name = "id")
18 public int getId() {
19 return id;
20 }
21
22 public void setId(int id) {
23 this.id = id;
24 }
25
26 @XmlElement(name = "firstname")
27 public String getFirstName() {
28 return firstName;
29 }
30
31 public void setFirstName(String firstName) {
32 this.firstName = firstName;
33 }
34
35 @XmlElement(name = "lastname")
36 public String getLastName() {
37 return lastName;
38 }
39
40 public void setLastName(String lastName) {
41 this.lastName = lastName;
42 }
43
44 @XmlElement(name = "dob")
45 public Date getDob() {
46 return dob;
47 }
48
49 public void setDob(Date dob) {
50 this.dob = dob;
51 }
52
53 @Override
54 public String toString() {
55 return "Report [id=" + id + ", firstname=" + firstName + ", lastName=" + lastName + ", DateOfBirth=" + dob
56 + "]";
57 }
58
59}
请注意,模型类域应与春季批量地图配置定义相同,即在我们的情况下, `property name="names" value="id,firstname,lastname,dob" 。
Spring Batch 场地定位
需要一个自定义 FieldSetMapper
来转换一个日期. 如果不需要转换数据类型,那么只需要使用 BeanWrapperFieldSetMapper
来自动地图值以名称。
1package com.journaldev.spring;
2
3import java.text.ParseException;
4import java.text.SimpleDateFormat;
5
6import org.springframework.batch.item.file.mapping.FieldSetMapper;
7import org.springframework.batch.item.file.transform.FieldSet;
8import org.springframework.validation.BindException;
9
10import com.journaldev.spring.model.Report;
11
12public class ReportFieldSetMapper implements FieldSetMapper<Report> {
13
14 private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
15
16 public Report mapFieldSet(FieldSet fieldSet) throws BindException {
17
18 Report report = new Report();
19 report.setId(fieldSet.readInt(0));
20 report.setFirstName(fieldSet.readString(1));
21 report.setLastName(fieldSet.readString(2));
22
23 // default format yyyy-MM-dd
24 // fieldSet.readDate(4);
25 String date = fieldSet.readString(3);
26 try {
27 report.setDob(dateFormat.parse(date));
28 } catch (ParseException e) {
29 e.printStackTrace();
30 }
31
32 return report;
33
34 }
35
36}
Spring Batch 元素处理器
现在,正如工作配置中定义的那样,一个 itemProcessor 将在 itemWriter 之前启动,我们为它创建了一个 CustomItemProcessor.java
类。
1package com.journaldev.spring;
2
3import org.springframework.batch.item.ItemProcessor;
4
5import com.journaldev.spring.model.Report;
6
7public class CustomItemProcessor implements ItemProcessor<Report, Report> {
8
9 public Report process(Report item) throws Exception {
10
11 System.out.println("Processing..." + item);
12 String fname = item.getFirstName();
13 String lname = item.getLastName();
14
15 item.setFirstName(fname.toUpperCase());
16 item.setLastName(lname.toUpperCase());
17 return item;
18 }
19
20}
我们可以在 ItemProcessor 实现中操纵数据,因为你可以看到我正在将姓氏和姓氏值转换为上方案例。
春季配置文件
在我们的春季批量配置文件中,我们已经导入了两个额外的配置文件 - context.xml
和 database.xml
。
1<beans xmlns="https://www.springframework.org/schema/beans"
2 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="
4 https://www.springframework.org/schema/beans
5 https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
6
7 <!-- stored job-meta in memory -->
8 <!--
9 <bean id="jobRepository"
10 class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
11 <property name="transactionManager" ref="transactionManager" />
12 </bean>
13 -->
14
15 <!-- stored job-meta in database -->
16 <bean id="jobRepository"
17 class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
18 <property name="dataSource" ref="dataSource" />
19 <property name="transactionManager" ref="transactionManager" />
20 <property name="databaseType" value="mysql" />
21 </bean>
22
23 <bean id="transactionManager"
24 class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
25
26 <bean id="jobLauncher"
27 class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
28 <property name="jobRepository" ref="jobRepository" />
29 </bean>
30
31</beans>
- jobRepository - JobRepository负责将每个Java对象存储在其正确的元数据表中
- transactionManager - 这负责执行交易,一旦 commit-interval的大小和处理的数据等同
- jobLauncher - 这是春分的核心。
1<beans xmlns="https://www.springframework.org/schema/beans"
2 xmlns:jdbc="https://www.springframework.org/schema/jdbc" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="https://www.springframework.org/schema/beans
4 https://www.springframework.org/schema/beans/spring-beans-4.3.xsd
5 https://www.springframework.org/schema/jdbc
6 https://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd">
7
8 <!-- connect to database -->
9 <bean id="dataSource"
10 class="org.springframework.jdbc.datasource.DriverManagerDataSource">
11 <property name="driverClassName" value="com.mysql.jdbc.Driver" />
12 <property name="url" value="jdbc:mysql://localhost:3306/Test" />
13 <property name="username" value="test" />
14 <property name="password" value="test123" />
15 </bean>
16
17 <bean id="transactionManager"
18 class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
19
20 <!-- create job-meta tables automatically -->
21 <!-- <jdbc:initialize-database data-source="dataSource"> <jdbc:script location="org/springframework/batch/core/schema-drop-mysql.sql"
22 /> <jdbc:script location="org/springframework/batch/core/schema-mysql.sql"
23 /> </jdbc:initialize-database> -->
24</beans>
Spring Batch 使用一些元数据表来存储批次工作信息. 我们可以从春季批次配置中创建它们,但建议通过手动执行 SQL 文件,正如您在上面的评论代码中所看到的那样。
春季餐桌
Spring Batch tables very closely match the Domain objects that represent them in Java. For example - JobInstance, JobExecution, JobParameters and StepExecution map to BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION, BATCH_JOB_EXECUTION_PARAMS and BATCH_STEP_EXECUTION respectively. ExecutionContext maps to both BATCH_JOB_EXECUTION_CONTEXT and BATCH_STEP_EXECUTION_CONTEXT. The JobRepository is responsible for saving and storing each java object into its correct table. Below are the details of each meta-data table.
- 联合国 ** 批次_ 任务_ 任务** : 贝特克-约克- INSTEG 表格中包含与 JobInstance. 2 相关的全部信息 。 Batch_job_execution_params: BATCH_JOB_Execution_PARAMS (英语). 表格中包含与JobParemeters 对象有关的所有信息.
- ** 批次_ 工作_ 执行** : BATCH_JOB_执行 表格中包含与 JobExecution 对象相关的数据。 每次运行任务时都会添加一行.
- ** 批次_步骤_执行** : BATCH_STEP_执行 表格中包含与 StepExecution 对象有关的所有信息 5。 ** 批次_ 工作_ 执行_ 文本** : BATCH_ Job_ Execution_ CONTEXT 主题曲 表格中包含与 Job 执行 Context 相关的数据。 每项任务执行都有一份工作执行协议,其中包含执行该特定任务所需的所有工作级别数据。 此数据通常代表失败后必须检索到的状态,以使一个工作Instance能够从它失败的地方重启.
- ** 批次_步骤_执行_文本** : BATCH_STEP_执行_CONTEXT 表格中包含与 Step 执行 Context 相关的数据。 每个步骤执行都有一个完全执行的文字,它包含着需要坚持执行某一步骤的所有数据. 此数据通常代表失败后必须检索到的状态,以使一个工作Instance能够从失败的地方重新启动.
- ** 批次_ 工作_ 执行_ seq** : 本表保留了任务的数据执行序列.
- ** 批次_步骤_执行_seq** : 本表保存了步执行顺序的数据.
- ** 批次_ job_seq** : 本表保留了工作序列数据,以防我们有多个工作,我们会得到多个行. ( (英语)
春季测试计划
我们的 Spring Batch 示例项目已经准备好了,最后一步是编写一个测试类来执行它作为一个 java 程序。
1package com.journaldev.spring;
2
3import org.springframework.batch.core.Job;
4import org.springframework.batch.core.JobExecution;
5import org.springframework.batch.core.JobParameters;
6import org.springframework.batch.core.JobParametersBuilder;
7import org.springframework.batch.core.launch.JobLauncher;
8import org.springframework.context.support.ClassPathXmlApplicationContext;
9
10public class App {
11 public static void main(String[] args) {
12
13 String[] springConfig = { "spring/batch/jobs/job-batch-demo.xml" };
14
15 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(springConfig);
16
17 JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
18 Job job = (Job) context.getBean("DemoJobXMLWriter");
19
20 JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis())
21 .toJobParameters();
22
23 try {
24
25 JobExecution execution = jobLauncher.run(job, jobParameters);
26 System.out.println("Exit Status : " + execution.getStatus());
27
28 } catch (Exception e) {
29 e.printStackTrace();
30 }
31
32 System.out.println("Done");
33 context.close();
34 }
35}
只需在程序上运行,你会得到输出xml如下。
1<?xml version="1.0" encoding="UTF-8"?><report><record id="1001"><dob>2013-07-29T00:00:00+05:30</dob><firstname>TOM</firstname><lastname>MOODY</lastname></record><record id="1002"><dob>2013-07-30T00:00:00+05:30</dob><firstname>JOHN</firstname><lastname>PARKER</lastname></record><record id="1003"><dob>2013-07-31T00:00:00+05:30</dob><firstname>HENRY</firstname><lastname>WILLIAMS</lastname></record></report>
那就是春班的例子,你可以从下面的链接下载最终项目。
[下载《春天小组示例项目》(LINK0)]
引用: 官方指南