- 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 - XML 到 MySQL
本章节,我们将创建一个使用 XML 读取器和 MySQL 写入器的 Spring Batch 应用。
读取器 - 应用中使用的读取器是 StaxEventItemReader,用于读取 XML 文档中的数据。
创建项目
创建一个新的 Maven 项目,具体步骤请参考 Spring Batch - 环境配置章节。
以下是本应用中使用的输入 XML 文档。该文档包含数据记录,这些记录指定了诸如教程 ID、教程作者、教程标题、提交日期、教程图标和教程描述之类的详细信息。
tutorial.xml
将此文件创建在 Maven 项目的 src > main > resources 文件夹中。
<?xml version="1.0" encoding="UTF-8"?> <tutorials> <tutorial> <tutorial_id>1001</tutorial_id> <tutorial_author>Sanjay</tutorial_author> <tutorial_title>Learn Java</tutorial_title> <submission_date>06-05-2007</submission_date> <tutorial_icon>https://tutorialspoint.com/java/images/java-minilogo.jpg</tutorial_icon> <tutorial_description>Java is a high-level programming language originally developed by Sun Microsystems and released in 1995. Java runs on a variety of platforms. This tutorial gives a complete understanding of Java.');</tutorial_description> </tutorial> <tutorial> <tutorial_id>1002</tutorial_id> <tutorial_author>Abdul S</tutorial_author> <tutorial_title>Learn MySQL</tutorial_title> <submission_date>19-04-2007</submission_date> <tutorial_icon>https://tutorialspoint.com/mysql/images/mysql-minilogo.jpg</tutorial_icon> <tutorial_description>MySQL is the most popular Open Source Relational SQL database management system. MySQL is one of the best RDBMS being used for developing web-based software applications. This tutorial will give you quick start with MySQL and make you comfortable with MySQL programming.</tutorial_description> </tutorial> <tutorial> <tutorial_id>1003</tutorial_id> <tutorial_author>Krishna Kasyap</tutorial_author> <tutorial_title>Learn JavaFX</tutorial_title> <submission_date>06-07-2017</submission_date> <tutorial_icon>https://tutorialspoint.com/javafx/images/javafx-minilogo.jpg</tutorial_icon> <tutorial_description>JavaFX is a Java library used to build Rich Internet Applications. The applications developed using JavaFX can run on various devices such as Desktop Computers, Mobile Phones, TVs, Tablets, etc. This tutorial, discusses all the necessary elements of JavaFX that are required to develop effective Rich Internet Applications</tutorial_description> </tutorial> </tutorials>
写入器 - 应用中使用的写入器是 JdbcBatchItemWriter,用于将数据写入 MySQL 数据库。假设我们已经在名为 "details" 的数据库中创建了一个表。
CREATE TABLE details.TUTORIALS( tutorial_id int(10) NOT NULL, tutorial_author VARCHAR(20), tutorial_title VARCHAR(50), submission_date VARCHAR(20), tutorial_icon VARCHAR(200), tutorial_description VARCHAR(1000) );
处理器 - 应用中使用的处理器是一个自定义处理器,它将每条记录的数据写入 PDF 文档。
在批处理过程中,如果读取了 "n" 条记录或数据元素,则对于每条记录,它将读取数据、处理数据并将数据写入写入器。为了处理数据,它依赖于传递的处理器。在本例中,在自定义处理器类中,我们编写了加载特定 PDF 文档、创建新页面以及以表格格式将数据项写入 PDF 的代码。
最后,如果您执行此应用程序,它将读取 XML 文档中的所有数据项,将它们存储到 MySQL 数据库中,并在给定的 PDF 文档中将其打印在各个页面上。
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> </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> </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 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd "> <import resource = "context.xml" /> <bean id = "itemProcessor" class = "CustomItemProcessor" /> <batch:job id = "helloWorldJob"> <batch:step id = "step1"> <batch:tasklet> <batch:chunk reader = "xmlItemReader" writer = "mysqlItemWriter" processor = "itemProcessor" commit-interval="1"> </batch:chunk> </batch:tasklet> </batch:step> </batch:job> <bean id = "xmlItemReader" class = "org.springframework.batch.item.xml.StaxEventItemReader"> <property name = "fragmentRootElementName" value = "tutorial" /> <property name = "resource" value = "classpath:tutorial.xml" /> <property name = "unmarshaller" ref = "customUnMarshaller" /> </bean> <bean id = "customUnMarshaller" class = "org.springframework.oxm.xstream.XStreamMarshaller"> <property name = "aliases"> <util:map id = "aliases"> <entry key = "tutorial" value = "Tutorial" /> </util:map> </property> </bean> <bean id = "mysqlItemWriter" class = "org.springframework.batch.item.database.JdbcBatchItemWriter"> <property name = "dataSource" ref = "dataSource" /> <property name = "sql"> <value> <![CDATA[insert into details.tutorials (tutorial_id, tutorial_author, tutorial_title, submission_date, tutorial_icon, tutorial_description) values (:tutorial_id, :tutorial_author, :tutorial_title, :submission_date, :tutorial_icon, :tutorial_description);]]> </value> </property> <property name = "itemSqlParameterSourceProvider"> <bean class = "org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" /> </property> </bean> </beans>
Context.xml
以下是 Spring Batch 应用程序的 context.xml 文件。在此文件中,我们将定义诸如作业存储库、作业启动器和事务管理器之类的 bean。
将此文件创建在 Maven 项目的 src > main > resources 文件夹中。
<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> <!-- connect to MySQL database --> <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> <!-- 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
以下是处理器类。在这个类中,我们编写了应用程序处理的代码。在这里,我们正在加载 PDF 文档,创建一个新页面,创建一个表,并在表中为每条记录插入以下值:教程 ID、教程名称、作者、提交日期。
将此类创建在 Maven 项目的 src > main > java 文件夹中。
import java.io.File; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.springframework.batch.item.ItemProcessor; public class CustomItemProcessor implements ItemProcessor<Tutorial, Tutorial> { public static void drawTable(PDPage page, PDPageContentStream contentStream, float y, float margin, String[][] content) throws IOException { final int rows = content.length; final int cols = content[0].length; final float rowHeight = 50; final float tableWidth = page.getMediaBox().getWidth()-(2*margin); final float tableHeight = rowHeight * rows; final float colWidth = tableWidth/(float)cols; final float cellMargin=5f; // draw the rows float nexty = y ; for (int i = 0; i <= rows; i++) { contentStream.drawLine(margin,nexty,margin+tableWidth,nexty); nexty-= rowHeight; } //draw the columns float nextx = margin; for (int i = 0; i <= cols; i++) { contentStream.drawLine(nextx,y,nextx,y-tableHeight); nextx += colWidth; } // now add the text contentStream.setFont(PDType1Font.HELVETICA_BOLD,12); float textx = margin+cellMargin; float texty = y-15; for(int i = 0; i < content.length; i++){ for(int j = 0 ; j < content[i].length; j++){ String text = content[i][j]; contentStream.beginText(); contentStream.moveTextPositionByAmount(textx,texty); contentStream.drawString(text); contentStream.endText(); textx += colWidth; } texty-=rowHeight; textx = margin+cellMargin; } } private void createPDFDocument() throws IOException { // Creating PDF document object PDDocument document = new PDDocument(); // Saving the document document.save("E:/Examples/test.pdf"); System.out.println("PDF created"); // Closing the document document.close(); } @Override public Tutorial process(Tutorial item) throws Exception { System.out.println("Processing..." + item); createPDFDocument(); // Creating PDF document object PDDocument doc = PDDocument.load(new File("E:/Examples/test.pdf")); // Creating a blank page PDPage page = new PDPage(); doc.addPage( page ); PDPageContentStream contentStream = new PDPageContentStream(doc, page); String[][] content = {{"Id",""+item.getTutorial_id()}, {"Title", item.getTutorial_title()}, {"Authour", item.getTutorial_author()}, {"Submission Date", item.getSubmission_date()}} ; drawTable(page, contentStream, 700, 100, content); contentStream.close(); doc.save("E:/Examples/test.pdf" ); System.out.println("Hello"); return item; } }
TutorialFieldSetMapper.java
以下是 ReportFieldSetMapper 类,它将数据设置到 Tutorial 类。
将此类创建在 Maven 项目的 src > main > java 文件夹中。
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> { @Override public Tutorial mapFieldSet(FieldSet fieldSet) throws BindException { // instantiating the Tutorial class Tutorial tutorial = new Tutorial(); // Setting the fields from XML tutorial.setTutorial_id(fieldSet.readInt(0)); tutorial.setTutorial_title(fieldSet.readString(1)); tutorial.setTutorial_author(fieldSet.readString(2)); tutorial.setTutorial_icon(fieldSet.readString(3)); tutorial.setTutorial_description(fieldSet.readString(4)); return tutorial; } }
Tutorial.java
以下是Tutorial 类。它是一个带有setter和getter方法的简单类。
将此类创建在 Maven 项目的 src > main > java 文件夹中。
public class Tutorial { private int tutorial_id; private String tutorial_author; private String tutorial_title; private String submission_date; private String tutorial_icon; private String tutorial_description; @Override public String toString() { return " [id=" + tutorial_id + ", author=" + tutorial_author + ", title=" + tutorial_title + ", date=" + submission_date + ", icon =" +tutorial_icon +", description = "+tutorial_description+"]"; } public int getTutorial_id() { return tutorial_id; } public void setTutorial_id(int tutorial_id) { this.tutorial_id = tutorial_id; } public String getTutorial_author() { return tutorial_author; } public void setTutorial_author(String tutorial_author) { this.tutorial_author = tutorial_author; } public String getTutorial_title() { return tutorial_title; } public void setTutorial_title(String tutorial_title) { this.tutorial_title = tutorial_title; } public String getSubmission_date() { return submission_date; } public void setSubmission_date(String submission_date) { this.submission_date = submission_date; } public String getTutorial_icon() { return tutorial_icon; } public void setTutorial_icon(String tutorial_icon) { this.tutorial_icon = tutorial_icon; } public String getTutorial_description() { return tutorial_description; } public void setTutorial_description(String tutorial_description) { this.tutorial_description = tutorial_description; } }
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"); // create the pdf createPDFDocument(); // Executing the JOB JobExecution execution = jobLauncher.run(job, new JobParameters()); System.out.println("Exit Status : " + execution.getStatus()); } private static void createPDFDocument() throws IOException { // Creating PDF document object PDDocument document = new PDDocument(); // Saving the document document.save("E:/Examples/test.pdf"); System.out.println("PDF created"); // Closing the document document.close(); } }
输出
在 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 3 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.495 s [INFO] Finished at: 2024-07-31T12:14:52+05:30 [INFO] [1m------------------------------------------------------------------------[m
要检查上述 SpringBatch 程序的输出,请右键单击 App.java 类并选择运行方式 -> Java 应用程序。它将产生以下输出:
Jul 31, 2024 12:16:16 PM org.springframework.batch.core.launch.support.SimpleJobLauncher afterPropertiesSet INFO: No TaskExecutor has been set, defaulting to synchronous executor. PDF created Jul 31, 2024 12:16:19 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run INFO: Job: [FlowJob: [name=helloWorldJob]] launched with the following parameters: [{}] Jul 31, 2024 12:16:20 PM org.springframework.batch.core.job.SimpleStepHandler handleStep INFO: Executing step: [step1] Security framework of XStream not explicitly initialized, using predefined black list on your own risk. Processing... [id=1001, author=Sanjay, title=Learn Java, date=06-05-2007, icon =https://tutorialspoint.com/java/images/java-minilogo.jpg, description = Java is a high-level programming language originally developed by Sun Microsystems and released in 1995. Java runs on a variety of platforms. This tutorial gives a complete understanding of Java.');] Processing... [id=1002, author=Abdul S, title=Learn MySQL, date=19-04-2007, icon =https://tutorialspoint.com/mysql/images/mysql-minilogo.jpg, description = MySQL is the most popular Open Source Relational SQL database management system. MySQL is one of the best RDBMS being used for developing web-based software applications. This tutorial will give you quick start with MySQL and make you comfortable with MySQL programming.] Processing... [id=1003, author=Krishna Kasyap, title=Learn JavaFX, date=06-07-2017, icon =https://tutorialspoint.com/javafx/images/javafx-minilogo.jpg, description = JavaFX is a Java library used to build Rich Internet Applications. The applications developed using JavaFX can run on various devices such as Desktop Computers, Mobile Phones, TVs, Tablets, etc. This tutorial, discusses all the necessary elements of JavaFX that are required to develop effective Rich Internet Applications] Jul 31, 2024 12:16:21 PM org.springframework.batch.core.step.AbstractStep execute INFO: Step: [step1] executed in 1s232ms Jul 31, 2024 12:16:21 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 1s484ms Exit Status : COMPLETED
如果您在数据库中验证 details.tutorial 表,它将显示以下输出:
tutorial_id | tutorial_author | tutorial_title | submission_date | tutorial_icon | tutorial_description |
---|---|---|---|---|---|
1001 | Sanjay | 学习 Java | 06-05-2007 | https://tutorialspoint.com/java/images/java-mini-logo.jpg | Java 是一种高级编程语言,最初由 Sun Microsystems 开发并于 1995 年发布。Java 运行在各种平台上。本教程全面讲解了 Java。 |
1002 | Abdul S | 学习 MySQL | 19-04-2007 | https://tutorialspoint.com/mysql/images/mysql-minilogo.jpg | MySQL 是最流行的开源关系型 SQL 数据库管理系统。MySQL 是用于开发基于 Web 的软件应用程序的最佳 RDBMS 之一。本教程将快速入门 MySQL,并让您熟悉 MySQL 编程。 |
1003 | 学习 JavaFX | Krishna Kasyap | 06-07-2017 | https://tutorialspoint.com/javafx/images/javafx-minilogo.jpg | MySQL 是最流行的开源关系型 SQL 数据库管理系统。MySQL 是用于开发基于 Web 的软件应用程序的最佳 RDBMS 之一。本教程将快速入门 MySQL,并让您熟悉 MySQL 编程。 |
这将生成一个 PDF,每页显示一条记录,如下所示。