Spring Boot - Serviço em lote

Você pode criar um arquivo JAR executável e executar o aplicativo Spring Boot usando os comandos Maven ou Gradle conforme mostrado abaixo -

Para Maven, você pode usar o comando fornecido abaixo -

mvn clean install

Após “BUILD SUCCESS”, você pode encontrar o arquivo JAR no diretório de destino.

Para Gradle, você pode usar o comando conforme mostrado -

gradle clean build

Depois de “BUILD SUCCESSFUL”, você pode encontrar o arquivo JAR no diretório build / libs.

Execute o arquivo JAR usando o comando fornecido aqui -

java –jar <JARFILE>

Agora, o aplicativo foi iniciado na porta 8080 do Tomcat, conforme mostrado.

Agora, acesse o URL http://localhost:8080/ no seu navegador da web e conecte o soquete da web e envie a saudação e receba a mensagem.

O Batch Service é um processo para executar mais de um comando em uma única tarefa. Neste capítulo, você aprenderá como criar serviço em lote em um aplicativo Spring Boot.

Vamos considerar um exemplo em que vamos salvar o conteúdo do arquivo CSV no HSQLDB.

Para criar um programa Batch Service, precisamos adicionar a dependência Spring Boot Starter Batch e a dependência HSQLDB em nosso arquivo de configuração de construção.

Os usuários do Maven podem adicionar as seguintes dependências no arquivo pom.xml.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
   <groupId>org.hsqldb</groupId>
   <artifactId>hsqldb</artifactId>
</dependency>

Os usuários do Gradle podem adicionar as seguintes dependências no arquivo build.gradle.

compile("org.springframework.boot:spring-boot-starter-batch")
compile("org.hsqldb:hsqldb")

Agora, adicione o arquivo de dados CSV simples em recursos de caminho de classe - src / main / resources e nomeie o arquivo como file.csv conforme mostrado -

William,John
Mike, Sebastian
Lawarance, Lime

Em seguida, escreva um script SQL para HSQLDB - no diretório de recursos do classpath - 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)
);

Crie uma classe POJO para o modelo USERS conforme mostrado -

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;
   }   
}

Agora, crie um processador intermediário para fazer as operações após a leitura dos dados do arquivo CSV e antes de gravar os dados no 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;
   }
}

Vamos criar um arquivo de configuração em lote, para ler os dados do CSV e gravar no arquivo SQL conforme mostrado abaixo. Precisamos adicionar a anotação @EnableBatchProcessing no arquivo de classe de configuração. A anotação @EnableBatchProcessing é usada para habilitar as operações em lote para seu aplicativo Spring Boot.

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();
   }
}

o reader() O método é usado para ler os dados do arquivo CSV e o método writer () é usado para escrever os dados no SQL.

Em seguida, teremos que escrever uma classe de Listener de notificação de conclusão de trabalho - usada para notificar após a conclusão do trabalho.

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.");
         }
      }
   }
}

Agora, crie um arquivo JAR executável e execute o aplicativo Spring Boot usando os seguintes comandos Maven ou Gradle.

Para Maven, use o comando conforme mostrado -

mvn clean install

Após “BUILD SUCCESS”, você pode encontrar o arquivo JAR no diretório de destino.

Para Gradle, você pode usar o comando conforme mostrado -

gradle clean build

Depois de “BUILD SUCCESSFUL”, você pode encontrar o arquivo JAR no diretório build / libs.

Execute o arquivo JAR usando o comando fornecido aqui -

java –jar <JARFILE>

Você pode ver a saída na janela do console como mostrado -