Spring Batch 简明教程

Spring Batch - MySQL to XML

在本章中,我们将创建一个 Spring Batch 应用程序,它使用 MySQL reader 和 XML Writer。

Reader − 应用程序中使用的 reader 是 JdbcCursorItemReader ,用来从 MySQL 数据库中读取数据。

假设我们在 MySQL 数据库中创建了一个表,如下所示 −

CREATE TABLE details.xml_mysql(
   person_id int(10) NOT NULL,
   sales VARCHAR(20),
   qty int(3),
   staffName VARCHAR(20),
   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)

Writer − 应用程序中使用的 Writer 是 StaxEventItemWriter ,用来将数据写入 XML 文件。

Processor − 我们在应用程序中使用的 Processor 是一个自定义处理器,它只是打印从 CSV 文件中读取的记录。

jobConfig.xml

以下是样例 Spring Batch 应用程序的配置文件。在该文件中,我们将定义 Job 和 Step。此外,我们还定义了 ItemReader、ItemProcessor 和 ItemWriter 的 bean。(在这里,我们将它们与其各自的类合并,并传递所需的属性值来配置它们。)

<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 = "../jobs/context.xml" />

   <bean id = "report" class = "Report" scope = "prototype" />
   <bean id = "itemProcessor" class = "CustomItemProcessor" />

   <batch:job id = "helloWorldJob">
      <batch:step id = "step1">
         <batch:tasklet>
            <batch:chunk reader = "dbItemReader"
               writer = "mysqlItemWriter" processor = "itemProcessor" commit-interval = "10">
            </batch:chunk>
         </batch:tasklet>
      </batch:step>
   </batch:job>

   <bean id = "dbItemReader"
      class = "org.springframework.batch.item.database.JdbcCursorItemReader" scope = "step">
      <property name = "dataSource" ref = "dataSource" />
      <property name = "sql" value = "select * from tutorials_data" />
      <property name = "rowMapper">
         <bean class = "TutorialRowMapper" />
      </property>
   </bean>
   <bean id = "mysqlItemWriter"
      class = "org.springframework.batch.item.xml.StaxEventItemWriter">
      <property name = "resource" value = "file:xml/outputs/tutorials.xml" />
      <property name = "marshaller" ref = "reportMarshaller" />
      <property name = "rootTagName" value = "Tutorial" />
   </bean>

   <bean id = "reportMarshaller" class = "org.springframework.oxm.jaxb.Jaxb2Marshaller">
      <property name = "classesToBeBound">
         <list>
            <value>Tutorial</value>
         </list>
      </property>
   </bean>
</beans>

Context.xml

以下是我们 Spring Batch 应用程序的 context.xml 。在该文件中,我们将定义 Bean,如 Job 存储库、Job 启动器和事务管理器。

<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.ResourcelessTransactionMana ger" />
   <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 = "driverClassName" value = "com.mysql.jdbc.Driver" />
      <property name = "url" value = "jdbc:mysql://localhost: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

以下是 Processor 类。在该类中,我们编写应用程序的处理代码。此处,我们打印每个记录的内容。

import org.springframework.batch.item.ItemProcessor;

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 类。

import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;

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_author(rs.getString("tutorial_author"));
      tutorial.setTutorial_title(rs.getString("tutorial_title"));
      tutorial.setSubmission_date(rs.getString("submission_date"));
      return tutorial;
   }
}

Tutorial.java

以下是 Tutorial 类。它是一个简单的 Java 类,具有 settergetter 方法。在该类中,我们使用注解来将该类的这些方法与 XML 文件的这些标记相关联。

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "details")
public class Tutorial {

   int tutorial_id;
   String tutorial_author;
   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;
   }

   public String toString() {
      return " [Tutorial Id=" + tutorial_id + ",
      Tutorial Author =" + tutorial_author  + ",
      Tutorial Title =" + tutorial_title + ",
      Submission Date =" + submission_date + "]";
   }
}

App.java

以下是启动批处理的代码。在该类中,我们将通过运行 JobLauncher 来启动 Batch 应用程序。

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  =  { "jobs/job_hello_world.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());
   }
}

执行此应用程序后,它将生成以下输出。

May 08, 2017 11:32:06 AM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3d646c37:
startup date [Mon May 08 11:32:06 IST 2017]; root of context hierarchy
May 08, 2017 11:32:06 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [jobs/job_hello_world.xml]
May 08, 2017 11:32:07 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
May 08, 2017 11:32:14 AM 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]
May 08, 2017 11:32:14 AM org.springframework.batch.core.launch.support.SimpleJobLauncher run
INFO: Job: [FlowJob: [name=helloWorldJob]] completed with the following parameters:
[{}] and the following status: [COMPLETED]
Exit Status : COMPLETED

这将生成包含以下内容的 XML 文件。

<?xml version = "1.0" encoding = "UTF-8"?>
<Tutorial>
   <details tutorial_id = "101">
      <submission_date>06-05-2007</submission_date>
      <tutorial_author>Sanjay</tutorial_author>
      <tutorial_title>Learn Java</tutorial_title>
   </details>

   <details tutorial_id = "102">
      <submission_date>19-04-2007</submission_date>
      <tutorial_author>Abdul S</tutorial_author>
      <tutorial_title>Learn MySQL</tutorial_title>
   </details>

   <details tutorial_id = "103">
      <submission_date>06-07-2017</submission_date>
      <tutorial_author>Krishna Kasyap</tutorial_author>
      <tutorial_title>Learn JavaFX</tutorial_title>
   </details>
</Tutorial>