Spring Boot - Service par lots

Vous pouvez créer un fichier JAR exécutable et exécuter l'application Spring Boot en utilisant les commandes Maven ou Gradle comme indiqué ci-dessous -

Pour Maven, vous pouvez utiliser la commande donnée ci-dessous -

mvn clean install

Après «BUILD SUCCESS», vous pouvez trouver le fichier JAR sous le répertoire cible.

Pour Gradle, vous pouvez utiliser la commande comme indiqué -

gradle clean build

Après «BUILD SUCCESSFUL», vous pouvez trouver le fichier JAR dans le répertoire build / libs.

Exécutez le fichier JAR en utilisant la commande donnée ici -

java –jar <JARFILE>

Maintenant, l'application a démarré sur le port Tomcat 8080 comme indiqué.

Maintenant, appuyez sur l'URL http://localhost:8080/ dans votre navigateur Web et connectez la prise Web, envoyez le message d'accueil et recevez le message.

Le service par lots est un processus permettant d'exécuter plusieurs commandes dans une seule tâche. Dans ce chapitre, vous allez apprendre à créer un service de traitement par lots dans une application Spring Boot.

Prenons un exemple où nous allons enregistrer le contenu du fichier CSV dans HSQLDB.

Pour créer un programme Batch Service, nous devons ajouter la dépendance Spring Boot Starter Batch et la dépendance HSQLDB dans notre fichier de configuration de construction.

Les utilisateurs Maven peuvent ajouter les dépendances suivantes dans le fichier pom.xml.

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

Les utilisateurs de Gradle peuvent ajouter les dépendances suivantes dans le fichier build.gradle.

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

Maintenant, ajoutez le fichier de données CSV simple sous les ressources du chemin de classe - src / main / resources et nommez le fichier comme file.csv comme indiqué -

William,John
Mike, Sebastian
Lawarance, Lime

Ensuite, écrivez un script SQL pour HSQLDB - sous le répertoire de ressources 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)
);

Créez une classe POJO pour le modèle USERS comme indiqué -

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

Maintenant, créez un processeur intermédiaire pour effectuer les opérations après la lecture des données du fichier CSV et avant d'écrire les données dans 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;
   }
}

Créons un fichier de configuration Batch, pour lire les données du CSV et écrire dans le fichier SQL comme indiqué ci-dessous. Nous devons ajouter l'annotation @EnableBatchProcessing dans le fichier de classe de configuration. L'annotation @EnableBatchProcessing est utilisée pour activer les opérations par lots pour votre application 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();
   }
}

le reader() est utilisée pour lire les données du fichier CSV et la méthode writer () est utilisée pour écrire une donnée dans le SQL.

Ensuite, nous devrons écrire une classe d'écouteur de notification de fin de travail - utilisée pour notifier après la fin du travail.

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

Maintenant, créez un fichier JAR exécutable et exécutez l'application Spring Boot à l'aide des commandes Maven ou Gradle suivantes.

Pour Maven, utilisez la commande comme indiqué -

mvn clean install

Après «BUILD SUCCESS», vous pouvez trouver le fichier JAR sous le répertoire cible.

Pour Gradle, vous pouvez utiliser la commande comme indiqué -

gradle clean build

Après «BUILD SUCCESSFUL», vous pouvez trouver le fichier JAR dans le répertoire build / libs.

Exécutez le fichier JAR en utilisant la commande donnée ici -

java –jar <JARFILE>

Vous pouvez voir la sortie dans la fenêtre de la console comme indiqué -