Spring Boot - Servizio batch

È possibile creare un file JAR eseguibile ed eseguire l'applicazione Spring Boot utilizzando i comandi Maven o Gradle come mostrato di seguito:

Per Maven, puoi utilizzare il comando indicato di seguito:

mvn clean install

Dopo "BUILD SUCCESS", è possibile trovare il file JAR nella directory di destinazione.

Per Gradle, puoi usare il comando come mostrato -

gradle clean build

Dopo "BUILD SUCCESSFUL", è possibile trovare il file JAR nella directory build / libs.

Esegui il file JAR utilizzando il comando fornito qui -

java –jar <JARFILE>

Ora, l'applicazione è stata avviata sulla porta Tomcat 8080 come mostrato.

Ora, premi l'URL http://localhost:8080/ nel browser Web e collegare la presa Web, inviare il saluto e ricevere il messaggio.

Il servizio batch è un processo per eseguire più di un comando in una singola attività. In questo capitolo imparerai come creare un servizio batch in un'applicazione Spring Boot.

Consideriamo un esempio in cui salveremo il contenuto del file CSV in HSQLDB.

Per creare un programma Batch Service, è necessario aggiungere la dipendenza Spring Boot Starter Batch e la dipendenza HSQLDB nel nostro file di configurazione della build.

Gli utenti Maven possono aggiungere le seguenti dipendenze nel file pom.xml.

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

Gli utenti Gradle possono aggiungere le seguenti dipendenze nel file build.gradle.

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

Ora aggiungi il semplice file di dati CSV in classpath resources - src / main / resources e assegna al file il nome file.csv come mostrato -

William,John
Mike, Sebastian
Lawarance, Lime

Quindi, scrivi uno script SQL per HSQLDB - nella directory delle risorse del percorso di classe - 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)
);

Crea una classe POJO per il modello USERS come mostrato -

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

Ora, crea un processore intermedio per eseguire le operazioni dopo la lettura dei dati dal file CSV e prima di scrivere i dati in 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;
   }
}

Creiamo un file di configurazione Batch, per leggere i dati da CSV e scrivere nel file SQL come mostrato di seguito. Dobbiamo aggiungere l'annotazione @EnableBatchProcessing nel file della classe di configurazione. L'annotazione @EnableBatchProcessing viene utilizzata per abilitare le operazioni batch per l'applicazione 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();
   }
}

Il reader() viene utilizzato per leggere i dati dal file CSV e il metodo writer () viene utilizzato per scrivere i dati nell'SQL.

Successivamente, dovremo scrivere una classe Listener di notifica del completamento del lavoro, utilizzata per notificare dopo il completamento del lavoro.

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

Ora, crea un file JAR eseguibile ed esegui l'applicazione Spring Boot utilizzando i seguenti comandi Maven o Gradle.

Per Maven, usa il comando come mostrato -

mvn clean install

Dopo "BUILD SUCCESS", è possibile trovare il file JAR nella directory di destinazione.

Per Gradle, puoi usare il comando come mostrato -

gradle clean build

Dopo "BUILD SUCCESSFUL", è possibile trovare il file JAR nella directory build / libs.

Esegui il file JAR utilizzando il comando fornito qui -

java –jar <JARFILE>

Puoi vedere l'output nella finestra della console come mostrato -