在本章中,我們將建立一個使用CSV Reader和XML Writer的簡單Spring Batch應用程式。
閱讀器 - 在應用程式中使用的閱讀器是FlatFileItemReader
,用於從CSV檔案中讀取資料。
以下是在此應用程式中使用的輸入CSV檔案。 本文件包含指定詳細資訊的資料記錄,如教學編號,教學作者,教學標題,提交日期,教學圖示和教學說明。
完整的專案目錄結構如下:
建立一個Maven專案,使用以下組態檔案(pom.xml):
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yiibai</groupId>
<artifactId>SpringBatchCSV2XML</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringBatch CSV to XML</name>
<url>http://maven.apache.org</url>
<properties>
<jdk.version>1.8</jdk.version>
<spring.version>4.3.8.RELEASE</spring.version>
<spring.batch.version>3.0.7.RELEASE</spring.batch.version>
<mysql.driver.version>5.1.25</mysql.driver.version>
<junit.version>4.11</junit.version>
</properties>
<dependencies>
<!-- Spring Core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/pdfbox/pdfbox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.0</version>
</dependency>
<!-- Spring jdbc, for database -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring XML to/back object -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- MySQL database driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
</dependency>
<!-- Spring Batch dependencies -->
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>${spring.batch.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-infrastructure</artifactId>
<version>${spring.batch.version}</version>
</dependency>
<!-- Spring Batch unit test -->
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<version>${spring.batch.version}</version>
</dependency>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>spring-batch</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>false</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
</build>
</project>
檔案:report.csv -
1001, "Sansu", "Learn Java", 16/12/2017
1002, "Leejas", "Learn MySQL", 19/04/2017
1003, "Kobe", "Learn JavaFX", 16/07/2018
Writer
是StaxEventItemWriter
,用於將資料寫入XML檔案。以下是Spring Batch應用程式範例的組態檔案。 在這個檔案中,我們將定義Job和Step。 除此之外,還為ItemReader
,ItemProcessor
和ItemWriter
定義了bean。 (在這裡,我們將它們與相應的類相關聯,並傳遞所需屬性的值來組態它們。)
檔案:jobconfig.xml -
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:batch = "http://www.springframework.org/schema/batch"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:util = "http://www.springframework.org/schema/util"
xsi:schemaLocation = "http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd ">
<import resource="context.xml" />
<bean id="report" class="Report" scope="prototype" />
<bean id="itemProcessor" class="com.yiibai.CustomItemProcessor" />
<batch:job id="helloWorldJob">
<batch:step id="step1">
<batch:tasklet>
<batch:chunk reader="cvsFileItemReader" writer="xmlItemWriter"
processor="itemProcessor" commit-interval="10">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="cvsFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="classpath:report.csv" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names"
value="tutorial_id,
tutorial_author, Tutorial_title, submission_date" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="com.yiibai.TutorialFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="xmlItemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
<property name="resource" value="file:xml/tutorials.xml" />
<property name="marshaller" ref="reportMarshaller" />
<property name="rootTagName" value="tutorials" />
</bean>
<bean id="reportMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.yiibai.Tutorial</value>
</list>
</property>
</bean>
</beans>
以下是Spring Batch應用程式的context.xml
。 在這個檔案中,我們將定義bean,如作業儲存庫,作業啟動器和事務管理器。
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:jdbc = "http://www.springframework.org/schema/jdbc"
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-3.2.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">
<!-- stored job-meta in database -->
<bean id = "jobRepository"
class = "org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name = "dataSource" ref = "dataSource" />
<property name = "transactionManager" ref = "transactionManager" />
<property name = "databaseType" value = "mysql" />
</bean>
<bean id = "transactionManager"
class = "org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id = "jobLauncher"
class = "org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name = "jobRepository" ref = "jobRepository" />
</bean>
<bean id = "dataSource" class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value = "com.mysql.jdbc.Driver" />
<property name = "url" value = "jdbc:mysql://localhost:3306/testdb" />
<property name = "username" value = "root" />
<property name = "password" value = "123456" />
</bean>
<!-- create job-meta tables automatically -->
<jdbc:initialize-database data-source = "dataSource">
<jdbc:script location = "org/springframework/batch/core/schema-drop-mysql.sql" />
<jdbc:script location = "org/springframework/batch/core/schema-mysql.sql" />
</jdbc:initialize-database>
</beans>
以下是處理器類。 在這個類中,在應用程式中編寫處理程式碼。 在這裡,列印每條記錄的內容。
import org.springframework.batch.item.ItemProcessor;
public class CustomItemProcessor implements ItemProcessor<Tutorial, Tutorial> {
public Tutorial process(Tutorial item) throws Exception {
System.out.println("Processing..." + item);
return item;
}
}
以下是TutorialFieldSetMapper
類,它將資料設定為Tutorial
類。
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.validation.BindException;
public class TutorialFieldSetMapper implements FieldSetMapper<Tutorial> {
public Tutorial mapFieldSet(FieldSet fieldSet) throws BindException {
//Instantiating the report object
Tutorial tutorial = new Tutorial();
//Setting the fields
tutorial.setTutorial_id(fieldSet.readInt(0));
tutorial.setTutorial_author(fieldSet.readString(1));
tutorial.setTutorial_title(fieldSet.readString(2));
tutorial.setSubmission_date(fieldSet.readString(3));
return tutorial;
}
}
以下是Tutorial
類。 它是一個簡單的帶有setter
和getter
方法的Java類。 在這個類中,我們使用注釋來將這個類的方法與XML檔案的標籤關聯起來。
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "tutorial")
public class Tutorial {
private int tutorial_id;
private String tutorial_author;
private String tutorial_title;
private String submission_date;
@XmlAttribute(name = "tutorial_id")
public int getTutorial_id() {
return tutorial_id;
}
public void setTutorial_id(int tutorial_id) {
this.tutorial_id = tutorial_id;
}
@XmlElement(name = "tutorial_author")
public String getTutorial_author() {
return tutorial_author;
}
public void setTutorial_author(String tutorial_author) {
this.tutorial_author = tutorial_author;
}
@XmlElement(name = "tutorial_title")
public String getTutorial_title() {
return tutorial_title;
}
public void setTutorial_title(String tutorial_title) {
this.tutorial_title = tutorial_title;
}
@XmlElement(name = "submission_date")
public String getSubmission_date() {
return submission_date;
}
public void setSubmission_date(String submission_date) {
this.submission_date = submission_date;
}
@Override
public String toString() {
return " [Tutorial id=" + tutorial_id + ",
Tutorial Author=" + tutorial_author + ",
Tutorial Title=" + tutorial_title + ",
Submission Date=" + submission_date + "]";
}
}
以下是啟動批次處理過程的程式碼。 在這個類中,通過執行JobLauncher來啟動批次處理應用程式。
package com.yiibai;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) throws Exception {
String[] springConfig = {"context.xml", "jobconfig.xml" };
// Creating the application context object
ApplicationContext context = new ClassPathXmlApplicationContext(springConfig);
// Creating the job launcher
JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
// Creating the job
Job job = (Job) context.getBean("helloWorldJob");
// Executing the JOB
JobExecution execution = jobLauncher.run(job, new JobParameters());
System.out.println("Exit Status : " + execution.getStatus());
}
}
在執行這個應用程式時,它將產生以下輸出。
資訊: Executed SQL script from class path resource [org/springframework/batch/core/schema-mysql.sql] in 7040 ms.
四月 28, 2018 2:32:15 下午 org.springframework.oxm.jaxb.Jaxb2Marshaller createJaxbContextFromClasses
資訊: Creating JAXBContext with classes to be bound [class com.yiibai.Tutorial]
四月 28, 2018 2:32:17 下午 org.springframework.batch.core.launch.support.SimpleJobLauncher run
資訊: Job: [FlowJob: [name=helloWorldJob]] launched with the following parameters: [{}]
四月 28, 2018 2:32:17 下午 org.springframework.batch.core.job.SimpleStepHandler handleStep
資訊: Executing step: [step1]
Processing... [Tutorial id=1001, Tutorial Author=Sansu, Tutorial Title=Learn Java, Submission Date=16/12/2017]
Processing... [Tutorial id=1002, Tutorial Author=Leejas, Tutorial Title=Learn MySQL, Submission Date=19/04/2017]
Processing... [Tutorial id=1003, Tutorial Author=Kobe, Tutorial Title=Learn JavaFX, Submission Date=16/07/2018]
四月 28, 2018 2:32:18 下午 org.springframework.batch.core.launch.support.SimpleJobLauncher run
資訊: Job: [FlowJob: [name=helloWorldJob]] completed with the following parameters: [{}] and the following status: [COMPLETED]
Exit Status : COMPLETED
這將生成一個包含以下內容的XML檔案。