- Spring Batch 教程
- Spring Batch - 首页
- Spring Batch - 概述
- Spring Batch - 环境
- Spring Batch - 架构
- Spring Batch - 应用
- Spring Batch - 配置
- 读取器、写入器和处理器
- Spring Batch - 基本应用
- Spring Batch - XML 到 MySQL
- Spring Batch - CSV 到 XML
- Spring Batch - MySQL 到 XML
- Spring Batch - MySQL 到平面文件
- Spring Batch 有用资源
- Spring Batch - 快速指南
- Spring Batch - 有用资源
- Spring Batch - 讨论
Spring Batch - MySQL 到平面文件
在本章中,我们将创建一个 Spring Batch 应用,它使用 MySQL 读取器和一个**平面文件**写入器(.txt)。
**读取器** - 我们在应用中使用的读取器是**JdbcCursorItemReader**,用于从 MySQL 数据库读取数据。
假设我们在 MySQL 数据库中创建了一个如下所示的表。
CREATE TABLE details.tutorialsdata( tutorial_id int NOT NULL, tutorial_author VARCHAR(20), tutorial_title VARCHAR(20), submission_date VARCHAR(20) );
假设我们向其中插入了以下记录。
mysql> select * from tutorialsdata; +-------------+-----------------+----------------+-----------------+ | tutorial_id | tutorial_author | tutorial_title | submission_date | +-------------+-----------------+----------------+-----------------+ | 101 | Sanjay | Learn Java | 06-05-2007 | | 102 | Abdul S | Learn MySQL | 19-04-2007 | | 103 | Krishna Kasyap | Learn JavaFX | 06-07-2017 | +-------------+-----------------+----------------+-----------------+ 3 rows in set (0.00 sec)
**写入器** - 我们在应用中使用的写入器是**FlatFileItemWriter**,用于将数据写入**平面文件**(.txt)。
**处理器** - 我们在应用中使用的处理器是一个自定义处理器,它只打印从 CSV 文件读取的记录。
创建项目
创建一个新的 Maven 项目,如Spring Batch - 环境章节中所述。
pom.xml
以下是此 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.tutorialspoint</groupId> <artifactId>SpringBatchSample</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>SpringBatchExample</name> <url>http://maven.apache.org</url> <properties> <jdk.version>21</jdk.version> <spring.version>5.3.14</spring.version> <spring.batch.version>4.3.4</spring.batch.version> <mysql.driver.version>8.4.0</mysql.driver.version> <junit.version>4.11</junit.version> <pdf.version>2.0.32</pdf.version> <xstream.version>1.4.17</xstream.version> <jaxb.version>2.3.1</jaxb.version> <jaxb.impl.version>2.3.4</jaxb.impl.version> </properties> <dependencies> <!-- Spring Core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</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>com.mysql</groupId> <artifactId>mysql-connector-j</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> <!-- pdfbox --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>${pdf.version}</version> </dependency> <!-- xstream --> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>${xstream.version}</version> </dependency> <!-- jaxb-api --> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>${jaxb.version}</version> </dependency> <!-- JAXB RI --> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>${jaxb.impl.version}</version> </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> </build> </project>
jobConfig.xml
以下是我们示例 Spring Batch 应用的配置文件。在此文件中,我们将定义作业和步骤。此外,我们还为 ItemReader、ItemProcessor 和 ItemWriter 定义 Bean。(在这里,我们将它们与相应的类关联,并传递所需属性的值以配置它们。)
在 Maven 项目的**src > main > resources**文件夹中创建此文件。
<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"> <import resource = "context.xml" /> <bean id = "tutorial" class = "Tutorial" scope = "prototype" /> <bean id = "itemProcessor" class = "CustomItemProcessor" /> <batch:job id = "helloWorldJob"> <batch:step id = "step1"> <batch:tasklet> <batch:chunk reader = "mysqlItemReader" writer = "flatFileItemWriter" processor = "itemProcessor" commit-interval = "10"> </batch:chunk> </batch:tasklet> </batch:step> </batch:job> <bean id = "mysqlItemReader" class = "org.springframework.batch.item.database.JdbcCursorItemReader" > <property name = "dataSource" ref = "dataSource" /> <property name = "sql" value = "select * from details.tutorialsdata" /> <property name = "rowMapper"> <bean class = "TutorialRowMapper" /> </property> </bean> <bean id = "flatFileItemWriter" class = " org.springframework.batch.item.file.FlatFileItemWriter"> <property name = "resource" value = "file:tutorials.txt"/> <property name = "lineAggregator"> <bean class = " org.springframework.batch.item.file.transform.PassThroughLineAggregator"/> </property> </bean> </beans>
Context.xml
以下是我们的 Spring Batch 应用的**context.xml**。在此文件中,我们将定义 Bean,如作业存储库、作业启动器和事务管理器。
在 Maven 项目的**src > main > resources**文件夹中创建此文件。
<beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc = "http://www.springframework.org/schema/jdbc" 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 = "dataSource" class = "org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name = "url" value = "jdbc:mysql://127.0.0.1:3306/details" /> <property name = "username" value = "myuser" /> <property name = "password" value = "password" /> </bean> <bean id = "jobLauncher" class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> <property name = "jobRepository" ref = "jobRepository" /> </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>
CustomItemProcessor.java
以下是处理器类。在此类中,我们编写应用中处理的代码。在这里,我们打印每条记录的内容。
在 Maven 项目的**src > main > java**文件夹中创建此类。
import org.springframework.batch.item.ItemProcessor; // Implementing the ItemProcessor interface public class CustomItemProcessor implements ItemProcessor<Tutorial, Tutorial> { @Override public Tutorial process(Tutorial item) throws Exception { System.out.println("Processing..." + item); return item; } }
TutorialRowMapper.java
以下是**TutorialRowMapper**类,它将数据设置为**Tutorial**类。
在 Maven 项目的**src > main > java**文件夹中创建此类。
public class TutorialRowMapper implements RowMapper<Tutorial> { @Override public Tutorial mapRow(ResultSet rs, int rowNum) throws SQLException { Tutorial tutorial = new Tutorial(); tutorial.setTutorial_id(rs.getInt("tutorial_id")); tutorial.setTutorial_title(rs.getString("tutorial_title")); tutorial.setTutorial_author(rs.getString("tutorial_author")); tutorial.setSubmission_date(rs.getString("submission_date")); return tutorial; } }
Tutorial.java
以下是**Tutorial**类。它是一个简单的 Java 类,带有**setter**和**getter**方法。在此类中,我们使用注解将此类的方法与 XML 文件的标签关联。
在 Maven 项目的**src > main > java**文件夹中创建此类。
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 + "]"; } }
App.java
以下是启动批处理过程的代码。在此类中,我们将通过运行 JobLauncher 来启动 Batch 应用。
在 Maven 项目的**src > main > java**文件夹中创建此类。
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 = { "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()); } }
输出
在 Eclipse 中右键单击项目,选择**以...方式运行 -> Maven 构建**。将目标设置为**clean package**并运行项目。您将看到以下输出。
[INFO] Scanning for projects... [INFO] [INFO] [1m----------------< [0;36mcom.tutorialspoint:SpringBatchSample[0;1m >----------------[m [INFO] [1mBuilding SpringBatchExample 1.0-SNAPSHOT[m [INFO] from pom.xml [INFO] [1m--------------------------------[ jar ]---------------------------------[m [INFO] [INFO] [1m--- [0;32mclean:3.2.0:clean[m [1m(default-clean)[m @ [36mSpringBatchSample[0;1m ---[m [INFO] Deleting C:\Users\Tutorialspoint\eclipse-workspace\SpringBatchSample\target [INFO] [INFO] [1m--- [0;32mresources:3.3.1:resources[m [1m(default-resources)[m @ [36mSpringBatchSample[0;1m ---[m [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 4 resources from src\main\resources to target\classes [INFO] [INFO] [1m--- [0;32mcompiler:2.3.2:compile[m [1m(default-compile)[m @ [36mSpringBatchSample[0;1m ---[m [WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent! [INFO] Compiling 5 source files to C:\Users\Tutorialspoint\eclipse-workspace\SpringBatchSample\target\classes [INFO] [INFO] [1m--- [0;32mresources:3.3.1:testResources[m [1m(default-testResources)[m @ [36mSpringBatchSample[0;1m ---[m [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource from src\test\resources to target\test-classes [INFO] [INFO] [1m--- [0;32mcompiler:2.3.2:testCompile[m [1m(default-testCompile)[m @ [36mSpringBatchSample[0;1m ---[m [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] [1m--- [0;32msurefire:3.1.2:test[m [1m(default-test)[m @ [36mSpringBatchSample[0;1m ---[m [INFO] [INFO] [1m--- [0;32mjar:3.3.0:jar[m [1m(default-jar)[m @ [36mSpringBatchSample[0;1m ---[m [INFO] Building jar: C:\Users\Tutorialspoint\eclipse-workspace\SpringBatchSample\target\spring-batch.jar [INFO] [1m------------------------------------------------------------------------[m [INFO] [1;32mBUILD SUCCESS[m [INFO] [1m------------------------------------------------------------------------[m [INFO] Total time: 3.323 s [INFO] Finished at: 2024-07-31T13:35:50+05:30 [INFO] [1m------------------------------------------------------------------------[m
要检查上述 SpringBatch 程序的输出,请右键单击 App.java 类并选择**以...方式运行 -> Java 应用**。它将产生以下输出 -
Jul 31, 2024 1:36:25 PM org.springframework.batch.core.launch.support.SimpleJobLauncher afterPropertiesSet INFO: No TaskExecutor has been set, defaulting to synchronous executor. Jul 31, 2024 1:36:28 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run INFO: Job: [FlowJob: [name=helloWorldJob]] launched with the following parameters: [{}] Jul 31, 2024 1:36:28 PM org.springframework.batch.core.job.SimpleStepHandler handleStep INFO: Executing step: [step1] Processing... [Tutorial id=101,Tutorial Author=Sanjay,Tutorial Title=Learn Java,Submission Date=06-05-2007] Processing... [Tutorial id=102,Tutorial Author=Abdul S,Tutorial Title=Learn MySQL,Submission Date=19-04-2007] Processing... [Tutorial id=103,Tutorial Author=Krishna Kasyap,Tutorial Title=Learn JavaFX,Submission Date=06-07-2017] Jul 31, 2024 1:36:28 PM org.springframework.batch.core.step.AbstractStep execute INFO: Step: [step1] executed in 191ms Jul 31, 2024 1:36:28 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run INFO: Job: [FlowJob: [name=helloWorldJob]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 515ms Exit Status : COMPLETED
这将生成一个 TXT 文件(根文件夹中的 tutorials.txt),其内容如下。
[Tutorial id=101,Tutorial Author=Sanjay,Tutorial Title=Learn Java,Submission Date=06-05-2007] [Tutorial id=102,Tutorial Author=Abdul S,Tutorial Title=Learn MySQL,Submission Date=19-04-2007] [Tutorial id=103,Tutorial Author=Krishna Kasyap,Tutorial Title=Learn JavaFX,Submission Date=06-07-2017]