Spring Boot 简明教程
Spring Boot - Batch Service
您可以创建一个可执行 JAR 文件,并使用 Maven 或 Gradle 命令运行 Spring Boot 应用程序,如下所示 −
You can create an executable JAR file, and run the Spring Boot application by using the Maven or Gradle commands as shown below −
对于 Maven,你可以使用下面给出的命令 −
For Maven, you can use the command given below −
mvn clean install
“BUILD SUCCESS”之后,您可以在目标目录中找到 JAR 文件。
After “BUILD SUCCESS”, you can find the JAR file under the target directory.
对于 Gradle,您可以使用如下命令:−
For Gradle, you can use the command as shown −
gradle clean build
“BUILD SUCCESSFUL”之后,您可以在 build/libs 目录中找到 JAR 文件。
After “BUILD SUCCESSFUL”, you can find the JAR file under the build/libs directory.
使用此处提供的命令运行 JAR 文件 −
Run the JAR file by using the command given here −
java –jar <JARFILE>
现在,该应用程序已经启动在所示的 Tomcat 端口 8080 上。
Now, the application has started on the Tomcat port 8080 as shown.
现在,在您的 Web 浏览器中访问 URL http://localhost:8080/ 并连接 Websocket,发送问候语并接收消息。
Now, hit the URL http://localhost:8080/ in your web browser and connect the web socket and send the greeting and receive the message.
批处理服务是一个在单个任务中执行多条命令的过程。在本章中,您将学习如何在 Spring Boot 应用程序中创建批处理服务。
Batch Service is a process to execute more than one command in a single task. In this chapter, you are going to learn how to create batch service in a Spring Boot application.
让我们考虑一个示例,其中我们要将 CSV 文件内容保存到 HSQLDB 中。
Let us consider an example where we are going to save the CSV file content into HSQLDB.
要创建批处理服务程序,我们需要在构建配置文件中添加 Spring Boot Starter Batch 依赖项和 HSQLDB 依赖项。
To create a Batch Service program, we need to add the Spring Boot Starter Batch dependency and HSQLDB dependency in our build configuration file.
Maven 用户可以在 pom.xml 文件中添加以下依赖项。
Maven users can add the following dependencies in pom.xml file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
</dependency>
Gradle 用户可以在 build.gradle 文件中添加以下依赖项。
Gradle users can add the following dependencies in build.gradle file.
compile("org.springframework.boot:spring-boot-starter-batch")
compile("org.hsqldb:hsqldb")
现在,在类路径资源下添加简单的 CSV 数据文件 – src/main/resources,并将文件命名为 file.csv,如下所示 −
Now, add the simple CSV data file under classpath resources – src/main/resources and name the file as file.csv as shown −
William,John
Mike, Sebastian
Lawarance, Lime
接下来,写入 HSQLDB 的 SQL 脚本 – 在类路径资源目录下 – request_fail_hystrix_timeout
Next, write a SQL script for HSQLDB – under the classpath resource directory – request_fail_hystrix_timeout
DROP TABLE USERS IF EXISTS;
CREATE TABLE USERS (
user_id BIGINT IDENTITY NOT NULL PRIMARY KEY,
first_name VARCHAR(20),
last_name VARCHAR(20)
);
创建一个 USERS 模型的 POJO 类,如下所示 −
Create a POJO class for USERS model as shown −
package com.tutorialspoint.batchservicedemo;
public class User {
private String lastName;
private String firstName;
public User() {
}
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return "firstName: " + firstName + ", lastName: " + lastName;
}
}
现在,创建一个中间处理器在从 CSV 文件中读取数据之后并在将数据写入到 SQL 之前执行操作。
Now, create an intermediate processor to do the operations after the reading the data from the CSV file and before writing the data into SQL.
package com.tutorialspoint.batchservicedemo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
public class UserItemProcessor implements ItemProcessor<User, User> {
private static final Logger log = LoggerFactory.getLogger(UserItemProcessor.class);
@Override
public User process(final User user) throws Exception {
final String firstName = user.getFirstName().toUpperCase();
final String lastName = user.getLastName().toUpperCase();
final User transformedPerson = new User(firstName, lastName);
log.info("Converting (" + user + ") into (" + transformedPerson + ")");
return transformedPerson;
}
}
让我们创建一个批处理配置文件,从 CSV 中读取数据并写入到 SQL 文件中,如下所示。我们需要在配置文件中添加 @EnableBatchProcessing 注解。@EnableBatchProcessing 注解用于为您的 Spring Boot 应用程序启用批处理操作。
Let us create a Batch configuration file, to read the data from CSV and write into the SQL file as shown below. We need to add the @EnableBatchProcessing annotation in the configuration class file. The @EnableBatchProcessing annotation is used to enable the batch operations for your Spring Boot application.
package com.tutorialspoint.batchservicedemo;
import javax.sql.DataSource;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
public DataSource dataSource;
@Bean
public FlatFileItemReader<User> reader() {
FlatFileItemReader<User> reader = new FlatFileItemReader<User>();
reader.setResource(new ClassPathResource("file.csv"));
reader.setLineMapper(new DefaultLineMapper<User>() {
{
setLineTokenizer(new DelimitedLineTokenizer() {
{
setNames(new String[] { "firstName", "lastName" });
}
});
setFieldSetMapper(new BeanWrapperFieldSetMapper<User>() {
{
setTargetType(User.class);
}
});
}
});
return reader;
}
@Bean
public UserItemProcessor processor() {
return new UserItemProcessor();
}
@Bean
public JdbcBatchItemWriter<User> writer() {
JdbcBatchItemWriter<User> writer = new JdbcBatchItemWriter<User>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<User>());
writer.setSql("INSERT INTO USERS (first_name, last_name) VALUES (:firstName, :lastName)");
writer.setDataSource(dataSource);
return writer;
}
@Bean
public Job importUserJob(JobCompletionNotificationListener listener) {
return jobBuilderFactory.get("importUserJob").incrementer(
new RunIdIncrementer()).listener(listener).flow(step1()).end().build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1").<User, User>chunk(10).reader(reader()).processor(processor()).writer(writer()).build();
}
}
reader() 方法用于从 CSV 文件中读取数据,writer() 方法用于将数据写入到 SQL 中。
The reader() method is used to read the data from the CSV file and writer() method is used to write a data into the SQL.
接下来,我们将不得不编写一个作业完成通知侦听器类 – 用于在作业完成后通知。
Next, we will have to write a Job Completion Notification Listener class – used to notify after the Job completion.
package com.tutorialspoint.batchservicedemo;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
@Component
public class JobCompletionNotificationListener extends JobExecutionListenerSupport {
private static final Logger log = LoggerFactory.getLogger(JobCompletionNotificationListener.class);
private final JdbcTemplate jdbcTemplate;
@Autowired
public JobCompletionNotificationListener(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void afterJob(JobExecution jobExecution) {
if (jobExecution.getStatus() == BatchStatus.COMPLETED) {
log.info("!!! JOB FINISHED !! It's time to verify the results!!");
List<User> results = jdbcTemplate.query(
"SELECT first_name, last_name FROM USERS", new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int row) throws SQLException {
return new User(rs.getString(1), rs.getString(2));
}
});
for (User person : results) {
log.info("Found <" + person + "> in the database.");
}
}
}
}
现在,创建一个可执行 JAR 文件,并使用以下 Maven 或 Gradle 命令运行 Spring Boot 应用程序。
Now, create an executable JAR file, and run the Spring Boot application by using the following Maven or Gradle commands.
对于 Maven,使用命令,如所示 −
For Maven, use the command as shown −
mvn clean install
“BUILD SUCCESS”之后,您可以在目标目录中找到 JAR 文件。
After “BUILD SUCCESS”, you can find the JAR file under the target directory.
对于 Gradle,您可以使用如下命令:−
For Gradle, you can use the command as shown −
gradle clean build
“BUILD SUCCESSFUL”之后,您可以在 build/libs 目录中找到 JAR 文件。
After “BUILD SUCCESSFUL”, you can find the JAR file under the build/libs directory.
使用此处提供的命令运行 JAR 文件 −
Run the JAR file by using the command given here −
java –jar <JARFILE>
您可以看到控制台窗口中的输出,如下所示 −
You can see the output in console window as shown −