Spring Batch - Guía rápida

Batch processinges un modo de procesamiento que implica la ejecución de una serie de trabajos complejos automatizados sin la interacción del usuario. Un proceso por lotes maneja datos masivos y se ejecuta durante mucho tiempo.

Varias aplicaciones empresariales requieren procesar grandes datos para realizar operaciones que involucran:

  • Eventos basados ​​en el tiempo, como cálculos periódicos.

  • Aplicaciones periódicas que se procesan repetidamente en grandes conjuntos de datos.

  • Aplicaciones que se ocupan del procesamiento y validación de los datos disponibles de forma transaccional.

Por lo tanto, el procesamiento por lotes se utiliza en aplicaciones empresariales para realizar dichas transacciones.

¿Qué es Spring Batch?

El lote de primavera es un lightweight framework que se utiliza para desarrollar Batch Applications que se utilizan en aplicaciones empresariales.

Además del procesamiento masivo, este marco proporciona funciones para:

  • Incluyendo registro y rastreo
  • Gestión de transacciones
  • Estadísticas de procesamiento de trabajos
  • Reinicio del trabajo
  • Gestión de saltos y recursos

También puede escalar aplicaciones de lotes de primavera utilizando sus técnicas de porcionado.

Características de Spring Batch

Las siguientes son las características notables de Spring Batch:

  • Flexibility- Las aplicaciones de Spring Batch son flexibles. Simplemente necesita cambiar un archivo XML para alterar el orden de procesamiento en una aplicación.

  • Maintainability- Las aplicaciones Spring Batch son fáciles de mantener. Un trabajo de Spring Batch incluye pasos y cada paso puede desacoplarse, probarse y actualizarse sin afectar los otros pasos.

  • Scalability- Usando las técnicas de porcionado, puede escalar las aplicaciones de Spring Batch. Estas técnicas le permiten:

    • Ejecute los pasos de un trabajo en paralelo.

    • Ejecute un solo hilo en paralelo.

  • Reliability - En caso de cualquier falla, puede reiniciar el trabajo exactamente desde donde se detuvo, desacoplando los pasos.

  • Support for multiple file formats - Spring Batch proporciona soporte para un gran conjunto de lectores y escritores, como XML, archivo plano, CSV, MYSQL, Hibernate, JDBC, Mongo, Neo4j, etc.

  • Multiple ways to launch a job - Puede iniciar un trabajo de Spring Batch utilizando aplicaciones web, programas Java, línea de comandos, etc.

Además de estos, las aplicaciones Spring Batch admiten:

  • Reintento automático después de un error.

  • Seguimiento del estado y las estadísticas durante la ejecución del lote y después de completar el procesamiento por lotes.

  • Para ejecutar trabajos simultáneos.

  • Servicios como registro, administración de recursos, omitir y reiniciar el procesamiento.

En este capítulo, explicaremos cómo configurar el entorno Spring Batch en Eclipse IDE. Antes de continuar con la instalación, asegúrese de haber instalado Eclipse en su sistema. Si no es así, descargue e instale Eclipse en su sistema.

Para obtener más información sobre Eclipse, consulte nuestro Tutorial de Eclipse.

Configuración de Spring Batch en Eclipse

Siga los pasos que se indican a continuación para configurar el entorno Spring Batch en Eclipse.

Step 1 - Instale Eclipse y abra un nuevo proyecto como se muestra en la siguiente captura de pantalla.

Step 2 - Cree un proyecto de muestra de Spring Batch como se muestra a continuación.

Step 3- Haga clic derecho en el proyecto y conviértalo en un proyecto Maven como se muestra a continuación. Una vez que lo convierta en un proyecto Maven, le dará unaPom.xmldonde debe mencionar las dependencias requeridas. A partir de entonces, eljar Los archivos de esos se descargarán automáticamente en su proyecto.

Step 4 - Ahora, en el pom.xml del proyecto, copie y pegue el siguiente contenido (dependencias para la aplicación por lotes de primavera) y actualice el proyecto.

<project xmlns = "http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 
   http://maven.apache.org/maven-v4_0_0.xsd"> 
   <modelVersion>4.0.0</modelVersion> 
   <groupId>com.tutorialspoint</groupId> 
   <artifactId>SpringBatchSample</artifactId> 
   <packaging>jar</packaging> 
   <version>1.0-SNAPSHOT</version> 
   <name>SpringBatchExample</name>
   <url>http://maven.apache.org</url>  
 
   <properties> 
      <jdk.version>1.8</jdk.version> 
      <spring.version>4.3.8.RELEASE</spring.version> 
      <spring.batch.version>3.0.7.RELEASE</spring.batch.version> 
      <mysql.driver.version>5.1.25</mysql.driver.version> 
      <junit.version>4.11</junit.version> 
   </properties>  
   
   <dependencies> 
      <!-- Spring Core --> 
      <dependency> 
         <groupId>org.springframework</groupId> 
         <artifactId>spring-core</artifactId> 
         <version>${spring.version}</version> 
      </dependency>  
      
      <!-- Spring jdbc, for database --> 
      <dependency> 
         <groupId>org.springframework</groupId> 
         <artifactId>spring-jdbc</artifactId> 
         <version>${spring.version}</version> 
      </dependency>  
      
      <!-- Spring XML to/back object --> 
      <dependency> 
         <groupId>org.springframework</groupId> 
         <artifactId>spring-oxm</artifactId> 
         <version>${spring.version}</version> 
      </dependency>  
   
      <!-- MySQL database driver --> 
      <dependency> 
         <groupId>mysql</groupId> 
         <artifactId>mysql-connector-java</artifactId>
         <version>${mysql.driver.version}</version> 
      </dependency>  
  
      <!-- Spring Batch dependencies --> 
      <dependency> 
         <groupId>org.springframework.batch</groupId> 
         <artifactId>spring-batch-core</artifactId> 
         <version>${spring.batch.version}</version> 
      </dependency> 
  
      <dependency> 
         <groupId>org.springframework.batch</groupId> 
         <artifactId>spring-batch-infrastructure</artifactId> 
         <version>${spring.batch.version}</version> 
      </dependency>  
  
      <!-- Spring Batch unit test --> 
      <dependency> 
         <groupId>org.springframework.batch</groupId> 
         <artifactId>spring-batch-test</artifactId> 
         <version>${spring.batch.version}</version> 
      </dependency>  
  
      <!-- Junit --> 
      <dependency> 
         <groupId>junit</groupId> 
         <artifactId>junit</artifactId> 
         <version>${junit.version}</version> 
         <scope>test</scope> 
      </dependency> 
   </dependencies> 
 
   <build> 
      <finalName>spring-batch</finalName> 
      <plugins> 
         <plugin> 
            <groupId>org.apache.maven.plugins</groupId> 
            <artifactId>maven-eclipse-plugin</artifactId>
            <version>2.9</version> 
            <configuration> 
               <downloadSources>true</downloadSources> 
               <downloadJavadocs>false</downloadJavadocs> 
            </configuration> 
         </plugin> 
      
         <plugin> 
            <groupId>org.apache.maven.plugins</groupId> 
            <artifactId>maven-compiler-plugin</artifactId> 
            <version>2.3.2</version> 
            <configuration> 
               <source>${jdk.version}</source> 
               <target>${jdk.version}</target> 
            </configuration> 
         </plugin> 
      </plugins> 
   </build> 
</project>

Finalmente, si observa las dependencias de Maven, puede observar que todas las jar Se han descargado archivos.

A continuación se muestra la representación esquemática de la arquitectura de Spring Batch. Como se muestra en la figura, la arquitectura contiene tres componentes principales, a saber,Application, Batch Corey Batch Infrastructure.

Application - Este componente contiene todos los trabajos y el código que escribimos usando el marco Spring Batch.

Batch Core - Este componente contiene todas las clases de API que se necesitan para controlar y lanzar un trabajo por lotes.

Batch Infrastructure - Este componente contiene los lectores, escritores y servicios utilizados por la aplicación y los componentes principales de Batch.

Componentes de Spring Batch

La siguiente ilustración muestra los diferentes componentes de Spring Batch y cómo están conectados entre sí.

Trabajo

En una aplicación Spring Batch, un trabajo es el proceso por lotes que se va a ejecutar. Funciona de principio a fin sin interrupción. Este trabajo se divide en pasos (o un trabajo contiene pasos).

Configuraremos un trabajo en Spring Batch usando un archivo XML o una clase Java. A continuación se muestra la configuración XML de un trabajo en Spring Batch.

<job id = "jobid"> 
   <step id = "step1" next = "step2"/> 
   <step id = "step2" next = "step3"/> 
   <step id = "step3"/> 
</job>

Un trabajo por lotes se configura dentro de las etiquetas <job> </job>. Tiene un atributo llamadoid. Dentro de estas etiquetas, definimos la definición y el orden de los pasos.

Restartable - En general, cuando se está ejecutando un trabajo e intentamos iniciarlo de nuevo, se considera restarty se iniciará de nuevo. Para evitar esto, debe configurar elrestartable valor para false Como se muestra abajo.

<job id = "jobid" restartable = "false" >

</job>

Paso

UN step es una parte independiente de un trabajo que contiene la información necesaria para definir y ejecutar el trabajo (su parte).

Como se especifica en el diagrama, cada paso se compone de un ItemReader, ItemProcessor (opcional) y un ItemWriter. A job may contain one or more steps.

Lectores, escritores y procesadores

Un item reader lee datos en una aplicación Spring Batch de una fuente en particular, mientras que un item writer escribe datos de la aplicación Spring Batch en un destino en particular.

Un Item processores una clase que contiene el código de procesamiento que procesa los datos leídos en el lote de primavera. Si la aplicación lee"n" registros, el código en el procesador se ejecutará en cada registro.

Cuando no se da ningún lector y escritor, taskletactúa como procesador para SpringBatch. Procesa solo una tarea. Por ejemplo, si estamos escribiendo un trabajo con un simple paso en el que leemos datos de la base de datos MySQL, los procesamos y los escribimos en un archivo (plano), entonces nuestro paso usa:

  • UN reader que lee de la base de datos MySQL.

  • UN writer que escribe en un archivo plano.

  • UN custom processor que procesa los datos según nuestro deseo.

<job id = "helloWorldJob"> 
   <step id = "step1"> 
      <tasklet> 
         <chunk reader = "mysqlReader" writer = "fileWriter" 
            processor = "CustomitemProcessor" ></chunk> 
      </tasklet> 
   </step> 
</ job>

Spring Batch proporciona una larga lista de readers y writers. Usando estas clases predefinidas, podemos definir beans para ellas. Discutiremosreaders y writers con mayor detalle en los capítulos siguientes.

JobRepository

Un repositorio de trabajos en Spring Batch proporciona operaciones de creación, recuperación, actualización y eliminación (CRUD) para las implementaciones de JobLauncher, Job y Step. Definiremos un repositorio de trabajos en un archivo XML como se muestra a continuación.

<job-repository id = "jobRepository"/>

Además de id, hay algunas opciones más (opcionales) disponibles. A continuación se muestra la configuración del repositorio de trabajos con todas las opciones y sus valores predeterminados.

<job-repository id = "jobRepository" 
   data-source = "dataSource" 
   transaction-manager = "transactionManager" 
   isolation-level-for-create = "SERIALIZABLE" 
   table-prefix = "BATCH_" 
   max-varchar-length = "1000"/>

In-Memory Repository - En caso de que no desee conservar los objetos de dominio de Spring Batch en la base de datos, puede configurar la versión en memoria del jobRepository como se muestra a continuación.

<bean id = "jobRepository" 
   class = "org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean ">
   <property name = "transactionManager" ref = "transactionManager"/>
</bean>

JobLauncher

JobLauncher es una interfaz que lanza el trabajo de Spring Batch con el given set of parameters. SampleJoblauncher es la clase que implementa el JobLauncherinterfaz. A continuación se muestra la configuración de JobLauncher.

<bean id = "jobLauncher" 
   class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
   <property name = "jobRepository" ref = "jobRepository" /> 
</bean>

JobInstance

UN JobInstancerepresenta la ejecución lógica de un trabajo; se crea cuando ejecutamos un trabajo. Cada instancia de trabajo se diferencia por el nombre del trabajo y los parámetros que se le pasan mientras se ejecuta.

Si falla la ejecución de JobInstance, se puede volver a ejecutar el mismo JobInstance. Por lo tanto, cada JobInstance puede tener varias ejecuciones de trabajos.

JobExecution y StepExecution

JobExecution y StepExecution son la representación de la ejecución de un trabajo / paso. Contienen la información de ejecución del trabajo / paso, como la hora de inicio (del trabajo / paso), la hora de finalización (del trabajo / paso).

Casi todos los ejemplos de este tutorial contienen los siguientes archivos:

  • Archivo de configuración (archivo XML)
  • Tasklet / procesador (clase Java)
  • Clase Java con setters y getters (clase Java (bean))
  • Clase de asignador (clase Java)
  • Clase de lanzador (clase Java)

Archivo de configuración

El archivo de configuración (XML) contiene lo siguiente:

  • los job y step definiciones.

  • Definición de frijoles readers y writers.

  • Definición de componentes como JobLauncher, JobRepository, Transaction Manager y Data Source.

En nuestros ejemplos, para una mejor comprensión, hemos dividido esto en dos archivos: job.xml archivo (define trabajo, paso, lector y escritor) y context.xml archivo (lanzador de trabajos, repositorio de trabajos, administrador de transacciones y fuente de datos).

Clase Mapper

La clase Mapper, dependiendo del lector, implementa interfaces como row mapper, field set mapper, etc. Contiene el código para obtener los datos del lector y configurarlo en una clase Java con setter y getter métodos (Java Bean).

Clase Java Bean

Una clase de Java con setters y getters(Bean Java) representa datos con múltiples valores. Actúa como una clase auxiliar. Pasaremos los datos de un componente (lector, escritor, procesador) a otro en forma de objeto de esta clase.

Tasklet / procesador

La clase Tasklet / procesador contiene el código de procesamiento de la aplicación Spring Batch. Un procesador es una clase que acepta un objeto que contiene los datos leídos, los procesa y devuelve los datos procesados ​​(en el objeto de formulario).

Clase de lanzador

Esta clase (App.java) contiene el código para iniciar la aplicación Spring Batch.

Mientras escribimos una aplicación Spring Batch, configuraremos el trabajo, paso, JobLauncher, JobRepository, Transaction Manager, lectores y escritores usando las etiquetas XML provistas en el espacio de nombres Spring Batch. Por lo tanto, debe incluir este espacio de nombres en su archivo XML como se muestra a continuación.

<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" 
   xsi:schemaLocation = "http://www.springframework.org/schema/batch 

   http://www.springframework.org/schema/batch/spring-batch-2.2.xsd 
   http://www.springframework.org/schema/bean   
   http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

En las siguientes secciones, discutiremos las diversas etiquetas, sus atributos y ejemplos, disponibles en el espacio de nombres de Spring Batch.

Trabajo

Esta etiqueta se utiliza para definir / configurar el trabajo del SpringBatch. Contiene un conjunto de pasos y se puede iniciar utilizando JobLauncher.

Esta etiqueta tiene 2 atributos que se enumeran a continuación:

S. No Atributo y descripción
1

Id

Es el Id del trabajo, es obligatorio especificar valor a este atributo.

2

restartable

Este es el atributo que se utiliza para especificar si el trabajo se puede reiniciar o no. Este atributo es opcional.

A continuación se muestra la configuración XML del trabajo de un SpringBatch.

<job id = "jobid" restartable = "false" > 
   . . . . . . . .  
   . . . . . . . .  
   . . . . . . . . // Step definitions 
</job>

Paso

Esta etiqueta se usa para definir / configurar los pasos de un trabajo SpringBatch. Tiene los siguientes tres atributos:

S. No Atributo y descripción
1

Id

Es el Id del trabajo, es obligatorio especificar valor a este atributo.

2

next

Es el atajo para especificar el siguiente paso.

3

parent

Se utiliza para especificar el nombre del bean padre del que debe heredar la configuración.

A continuación se muestra la configuración XML del paso de un SpringBatch.

<job id = "jobid"> 
   <step id = "step1" next = "step2"/> 
   <step id = "step2" next = "step3"/> 
   <step id = "step3"/> 
</job>

Pedazo

Esta etiqueta se utiliza para definir / configurar una parte de un tasklet. Tiene los siguientes cuatro atributos:

S. No Atributo y descripción
1

reader

Representa el nombre del bean lector de elementos. Acepta el valor del tipoorg.springframework.batch.item.ItemReader.

2

writer

Representa el nombre del bean lector de elementos. Acepta el valor del tipoorg.springframework.batch.item.ItemWriter.

3

processor

Representa el nombre del bean lector de elementos. Acepta el valor del tipoorg.springframework.batch.item.ItemProcessor.

4

commit-interval

Se utiliza para especificar la cantidad de elementos que se procesarán antes de realizar la transacción.

A continuación se muestra la configuración XML del fragmento de SpringBatch.

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

JobRepository

El JobRepository Bean se usa para configurar el JobRepository usando una base de datos relacional. Este bean está asociado con la clase de tipoorg.springframework.batch.core.repository.JobRepository.

S. No Atributo y descripción
1

dataSource

Se utiliza para especificar el nombre del bean que define la fuente de datos.

2

transactionManager

Se utiliza para especificar el nombre del bean que define el administrador de transacciones.

3

databaseType

Especifica el tipo de base de datos relacional que se usa en el repositorio de trabajos.

A continuación se muestra la configuración de ejemplo de JobRepository.

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

JobLauncher

El bean JobLauncher se utiliza para configurar JobLauncher. Está asociado con la claseorg.springframework.batch.core.launch.support.SimpleJobLauncher(en nuestros programas). Este frijol tiene una propiedad llamadajobrepository, y se utiliza para especificar el nombre del bean que define el jobrepository.

A continuación se muestra la configuración de ejemplo de jobLauncher.

<bean id = "jobLauncher" 
   class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
   <property name = "jobRepository" ref = "jobRepository" /> 
</bean>

TransactionManager

El bean TransactionManager se utiliza para configurar TransactionManager utilizando una base de datos relacional. Este bean está asociado con la clase de tipoorg.springframework.transaction.platform.TransactionManager.

<bean id = "transactionManager"
   class = "org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

Fuente de datos

El bean de origen de datos se utiliza para configurar el Datasource. Este bean está asociado con la clase de tipoorg.springframework.jdbc.datasource.DriverManagerDataSource.

S. No Atributo y descripción
1

driverClassName

Esto especifica el nombre de clase del controlador utilizado para conectarse con la base de datos.

2

url

Esto especifica la URL de la base de datos.

3

username

Esto especifica el nombre de usuario para conectarse con la base de datos.

4

password

Esto especifica la contraseña para conectarse con la base de datos.

A continuación se muestra la configuración de ejemplo del datasource.

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

Un Item Reader lee datos en la aplicación de lote de primavera de una fuente en particular, mientras que un Item Writer escribe datos de la aplicación Spring Batch en un destino en particular.

Un Item processores una clase que contiene el código de procesamiento que procesa los datos leídos en el lote de primavera. Si la aplicación lee n registros, el código del procesador se ejecutará en cada registro.

UN chunk es un elemento hijo de la tasklet. Se utiliza para realizar operaciones de lectura, escritura y procesamiento. Podemos configurar el lector, el escritor y los procesadores usando este elemento, en un paso como se muestra a continuación.

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

Spring Batch proporciona lectores y escritores para leer y escribir datos de varios sistemas de archivos / bases de datos como MongoDB, Neo4j, MySQL, XML, flatfile, CSV, etc.

Para incluir un lector en su aplicación, necesita definir un bean para ese lector, proporcionar valores a todas las propiedades requeridas dentro del bean y pasar el id de tal bean como un valor para el atributo del elemento chunk reader (igual por writer).

ItemReader

Es la entidad de un paso (de un proceso por lotes) que lee datos. Un ItemReader lee un artículo a la vez. Spring Batch proporciona una interfazItemReader. Todosreaders implementar esta interfaz.

A continuación se muestran algunas de las clases ItemReader predefinidas proporcionadas por Spring Batch para leer de varias fuentes.

Lector Propósito
FlatFIleItemReader Para leer datos de archivos planos.
StaxEventItemReader Para leer datos de archivos XML.
StoredProcedureItemReader Leer datos de los procedimientos almacenados de una base de datos.
JDBCPagingItemReader Leer datos de bases de datos relacionales.
MongoItemReader Para leer datos de MongoDB.
Neo4jItemReader Para leer datos de Neo4jItemReader.

Necesitamos configurar el ItemReaderscreando los frijoles. A continuación se muestra un ejemplo deStaxEventItemReader que lee datos de un archivo XML.

<bean id = "mysqlItemWriter" 
   class = "org.springframework.batch.item.xml.StaxEventItemWriter"> 
   <property name = "resource" value = "file:xml/outputs/userss.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>

Como se observó, durante la configuración, debemos especificar el nombre de clase respectivo del lector requerido y debemos proporcionar valores a todas las propiedades requeridas.

ItemWriter

Es el elemento de la stepde un proceso por lotes que escribe datos. Un ItemWriter escribe un elemento a la vez. Spring Batch proporciona una interfazItemWriter. Todos los escritores implementan esta interfaz.

A continuación se muestran algunas de las clases ItemWriter predefinidas proporcionadas por Spring Batch para leer de varias fuentes.

Escritor Propósito
FlatFIleItemWriter Para escribir datos en archivos planos.
StaxEventItemWriter Para escribir datos en archivos XML.
StoredProcedureItemWriter Escribir datos en los procedimientos almacenados de una base de datos.
JDBCPagingItemWriter Para escribir datos en bases de datos relacionales.
MongoItemWriter Para escribir datos en MongoDB.
Neo4jItemWriter Para escribir datos en Neo4j.

De la misma manera, necesitamos configurar ItemWriters creando los beans. A continuación se muestra un ejemplo deJdbcCursorItemReader que escribe datos en una base de datos MySQL.

<bean id = "dbItemReader"
   class = "org.springframework.batch.item.database.JdbcCursorItemReader" scope = "step">
   <property name = "dataSource" ref = "dataSource" />
   <property name = "sql" value = "select * from tutorialsdata" />
   <property name = "rowMapper">
      <bean class = "TutorialRowMapper" /> 
   </property>
</bean>

Procesador de artículos

ItemProcessor: Se utiliza un ItemProcessor para procesar los datos. Cuando el artículo dado no es válido, regresanull, de lo contrario, procesa el elemento dado y devuelve el resultado procesado. La interfazItemProcessor<I,O> representa al procesador.

Tasklet class - Cuando no reader y writerse dan, un Tasklet actúa como un procesador para SpringBatch. Procesa una sola tarea.

Podemos definir un procesador de artículos personalizado implementando la interfaz ItemProcessor del paquete org.springframework.batch.item.ItemProcessor. Esta clase ItemProcessor acepta un objeto y procesa los datos y devuelve los datos procesados ​​como otro objeto.

En un proceso por lotes, si "n"se leen registros o elementos de datos, luego, para cada registro, leerá los datos, los procesará y los escribirá en el escritor. Para procesar los datos, se transmite al procesador pasado.

Por ejemplo, supongamos que ha escrito un código para cargar un documento PDF en particular, crear una nueva página, escribir el elemento de datos en el PDF en formato tabular. Si ejecuta esta aplicación, lee todos los elementos de datos del documento XML, los almacena en la base de datos MySQL y los imprime en el documento PDF dado en páginas individuales.

Ejemplo

A continuación se muestra una clase ItemProcessor de muestra.

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

Este capítulo le muestra la aplicación básica de Spring Batch. Simplemente ejecutará untasklet a muestra un mensaje.

Nuestra aplicación Spring Batch contiene los siguientes archivos:

  • Configuration file- Este es un archivo XML donde definimos el Trabajo y los pasos del trabajo. (Si la aplicación también involucra lectores y escritores, entonces la configuración dereaders y writers también se incluye en este archivo.)

  • Context.xml - En este archivo, definiremos los beans como repositorio de trabajos, lanzador de trabajos y administrador de transacciones.

  • Tasklet class - En esta clase, escribiremos el trabajo del código de procesamiento (en este caso, muestra un mensaje simple)

  • Launcher class - en esta clase, lanzaremos la aplicación por lotes ejecutando el iniciador de trabajos.

jobConfig.xml

A continuación se muestra el archivo de configuración de nuestra aplicación Spring Batch de muestra.

<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" 
   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="context.xml" />      
   <!-- Defining a bean --> 
   <bean id = "tasklet" class = "a_sample.MyTasklet" />  
   <!-- Defining a job--> 
   <batch:job id = "helloWorldJob">  
      <!-- Defining a Step --> 
      <batch:step id = "step1"> 
         <tasklet ref = "tasklet"/>   
      </batch:step>    
   </batch:job>  
</beans>

Context.xml

Lo siguiente es el context.xml de nuestra aplicación Spring Batch.

<beans xmlns = "http://www.springframework.org/schema/beans" 
   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">  
   
   <bean id = "jobRepository"   
      class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> 
      <property name = "transactionManager" ref = "transactionManager" /> 
   </bean>     
     
   <bean id = "transactionManager" 
      class = "org.springframework.batch.support.transaction.ResourcelessTransactionManager" />  
   <bean id = "jobLauncher" 
      class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
      <property name = "jobRepository" ref = "jobRepository" /> 
   </bean> 
</beans>

Tasklet.java

A continuación se muestra la clase Tasklet que muestra un mensaje simple.

import org.springframework.batch.core.StepContribution; 
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;  

public class MyTasklet implements Tasklet { 
   
   @Override 
   public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception {  
      System.out.println("Hello This is a sample example of spring batch"); 
      return RepeatStatus.FINISHED; 
   } 
}

App.java

A continuación se muestra el código que inicia el proceso por lotes.

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 { 
  
      // System.out.println("hello"); 
      String[] springConfig  =  {"a_sample/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()); 
   }    
}

Al ejecutarse, el programa SpringBatch anterior producirá la siguiente salida:

Apr 24, 2017 4:40:54 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh 
INFO:Refreshing org[email protected]2ef1e4fa: startup date [Mon Apr 24 16:40:54 IST 2017]; root of context hierarchy 
Apr 24, 2017 4:40:54 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions  
Apr 24, 2017 4:40:54 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions  
INFO: Loading XML bean definitions 
Apr 24, 2017 4:40:54 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 
Apr 24, 2017 4:40:55 PM org.springframework.batch.core.launch.support.SimpleJobLauncher afterPropertiesSet 
INFO: No TaskExecutor has been set, defaulting to synchronous executor. 
Apr 24, 2017 4:40:55 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run 
INFO: Job: [FlowJob: [name=helloWorldJob]] launched with the following parameters: [{}] 
Apr 24, 2017 4:40:55 PM org.springframework.batch.core.job.SimpleStepHandler handleStep INFO: Executing step: [step1] 
Hello This is a sample example of spring batch 
Apr 24, 2017 4:40:55 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run 
INFO: Job: [FlowJob: [name=helloWorldJob]] completed with the following parameters: [{}] and the following status: [COMPLETED] 
Exit Status : COMPLETED

En este capítulo, crearemos una aplicación Spring Batch que usa un lector XML y un escritor MySQL.

Reader - El lector que estamos usando en la aplicación es StaxEventItemReader para leer datos de documentos XML.

A continuación se muestra el documento XML de entrada que estamos utilizando en esta aplicación. Este documento contiene registros de datos que especifican detalles como la identificación del tutorial, el autor del tutorial, el título del tutorial, la fecha de envío, el icono del tutorial y la descripción del tutorial.

<?xml version="1.0" encoding="UTF-8"?> 
<tutorials> 
   <tutorial>      
      <tutorial_id>1001</tutorial_id> 
      <tutorial_author>Sanjay</tutorial_author> 
      <tutorial_title>Learn Java</tutorial_title> 
      <submission_date>06-05-2007</submission_date> 
      <tutorial_icon>https://www.tutorialspoint.com/java/images/java-minilogo.jpg</tutorial_icon> 
      <tutorial_description>Java is a high-level programming language originally 
         developed by Sun Microsystems and released in 1995. 
         Java runs on a variety of platforms. 
         This tutorial gives a complete understanding of Java.');</tutorial_description> 
   </tutorial> 
    
   <tutorial>      
      <tutorial_id>1002</tutorial_id> 
      <tutorial_author>Abdul S</tutorial_author> 
      <tutorial_title>Learn MySQL</tutorial_title> 
      <submission_date>19-04-2007</submission_date> 
      <tutorial_icon>https://www.tutorialspoint.com/mysql/images/mysql-minilogo.jpg</tutorial_icon> 
      <tutorial_description>MySQL is the most popular 
         Open Source Relational SQL database management system. 
         MySQL is one of the best RDBMS being used for developing web-based software applications. 
         This tutorial will give you quick start with MySQL 
         and make you comfortable with MySQL programming.</tutorial_description> 
   </tutorial> 
    
   <tutorial>
      <tutorial_id>1003</tutorial_id> 
      <tutorial_author>Krishna Kasyap</tutorial_author> 
      <tutorial_title>Learn JavaFX</tutorial_title> 
      <submission_date>06-07-2017</submission_date> 
      <tutorial_icon>https://www.tutorialspoint.com/javafx/images/javafx-minilogo.jpg</tutorial_icon> 
      <tutorial_description>JavaFX is a Java library used to build Rich Internet Applications. 
         The applications developed using JavaFX can run on various devices 
         such as Desktop Computers, Mobile Phones, TVs, Tablets, etc. 
         This tutorial, discusses all the necessary elements of JavaFX that are required
         to develop effective Rich Internet Applications</tutorial_description> 
   </tutorial> 
</tutorials>

Writer - el writer que estamos usando en la aplicación es JdbcBatchItemWriterpara escribir los datos en la base de datos MySQL. Supongamos que hemos creado una tabla en MySQL dentro de una base de datos llamada"details".

CREATE TABLE details.TUTORIALS( 
   tutorial_id int(10) NOT NULL, 
   tutorial_author VARCHAR(20), 
   tutorial_title VARCHAR(50), 
   submission_date VARCHAR(20), 
   tutorial_icon VARCHAR(200), 
   tutorial_description VARCHAR(1000) 
);

Processor - El procesador que estamos usando en la aplicación es un procesador personalizado que escribe los datos de cada registro en el documento PDF.

En proceso por lotes, si "n"Se leyeron registros o elementos de datos, luego, para cada registro, leerá los datos, los procesará y los escribirá en el Writer. Para procesar los datos, se transmite al procesador pasado. En este caso, en la clase de procesador personalizado, hemos escrito código para cargar un documento PDF en particular, crear una nueva página, escribir el elemento de datos en el PDF en formato tabular.

Finalmente, si ejecuta esta aplicación, lee todos los elementos de datos del documento XML, los almacena en la base de datos MySQL y los imprime en el documento PDF dado en páginas individuales.

jobConfig.xml

A continuación se muestra el archivo de configuración de nuestra aplicación Spring Batch de muestra. En este archivo, definiremos el trabajo y los pasos. Además de estos, también definimos los beans para ItemReader, ItemProcessor y ItemWriter. (Aquí, los asociamos con sus respectivas clases y pasamos los valores de las propiedades requeridas para configurarlos).

<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 
      http://www.springframework.org/schema/util     
      http://www.springframework.org/schema/util/spring-util-3.0.xsd ">  
  
   <import resource = "../jobs/context.xml" /> 
  
   <bean id = "itemProcessor" class = "CustomItemProcessor" /> 
   <batch:job id = "helloWorldJob"> 
      <batch:step id = "step1"> 
         <batch:tasklet>           
            <batch:chunk reader = "xmlItemReader" writer = "mysqlItemWriter" processor = "itemProcessor">
            </batch:chunk> 
         </batch:tasklet> 
      </batch:step> 
   </batch:job> 
                
   <bean id = "xmlItemReader" 
      class = "org.springframework.batch.item.xml.StaxEventItemReader"> 
      <property name = "fragmentRootElementName" value = "tutorial" /> 
      <property name = "resource" value = "classpath:resources/tutorial.xml" /> 
      <property name = "unmarshaller" ref = "customUnMarshaller" /> 
   </bean> 
      
   <bean id = "customUnMarshaller" class = "org.springframework.oxm.xstream.XStreamMarshaller">
      <property name = "aliases"> 
         <util:map id = "aliases"> 
            <entry key = "tutorial" value = "Tutorial" />            
         </util:map> 
      </property> 
   </bean>  
   <bean id = "mysqlItemWriter" class = "org.springframework.batch.item.database.JdbcBatchItemWriter"> 
      <property name = "dataSource" ref = "dataSource" /> 
      <property name = "sql"> 
         <value> 
            <![CDATA[insert into details.tutorials (tutorial_id, tutorial_author, tutorial_title, 
               submission_date, tutorial_icon, tutorial_description) 
               values (:tutorial_id, :tutorial_author, :tutorial_title, :submission_date, 
               :tutorial_icon, :tutorial_description);]]>
         </value> 
      </property>   
      
      <property name = "itemSqlParameterSourceProvider"> 
         <bean class = "org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" /> 
      </property> 
   </bean> 
</beans>

Context.xml

Lo siguiente es el context.xmlde nuestra aplicación Spring Batch. En este archivo, definiremos los beans como repositorio de trabajos, lanzador de trabajos y administrador de transacciones.

<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

Lo siguiente es el processorclase. En esta clase, escribimos el código de procesamiento en la aplicación. Aquí, estamos cargando un documento PDF, creando una nueva página, creando una tabla e insertando los siguientes valores para cada registro: ID del tutorial, nombre del tutorial, autor, fecha de envío en la tabla.

import java.io.File; 
import java.io.IOException;  

import org.apache.pdfbox.pdmodel.PDDocument; 
import org.apache.pdfbox.pdmodel.PDPage; 
import org.apache.pdfbox.pdmodel.PDPageContentStream; 
import org.apache.pdfbox.pdmodel.font.PDType1Font; 
import org.springframework.batch.item.ItemProcessor;  

public class CustomItemProcessor implements ItemProcessor<Tutorial, Tutorial> {  
   
   public static void drawTable(PDPage page, PDPageContentStream contentStream, 
      float y, float margin, String[][] content) throws IOException { 
      final int rows = content.length; 
      final int cols = content[0].length; 
      final float rowHeight = 50; 
      final float tableWidth = page.getMediaBox().getWidth()-(2*margin); 
      final float tableHeight = rowHeight * rows; 
      final float colWidth = tableWidth/(float)cols; 
      final float cellMargin=5f;  
      
      // draw the rows 
      float nexty = y ; 
      for (int i = 0; i <= rows; i++) {   
         contentStream.drawLine(margin,nexty,margin+tableWidth,nexty); 
         nexty-= rowHeight; 
      }  
      
      //draw the columns 
      float nextx = margin; 
      for (int i = 0; i <= cols; i++) {
         contentStream.drawLine(nextx,y,nextx,y-tableHeight); 
         nextx += colWidth; 
      }  
      
      // now add the text    
      contentStream.setFont(PDType1Font.HELVETICA_BOLD,12);  
      
      float textx = margin+cellMargin; 
      float texty = y-15; 
      for(int i = 0; i < content.length; i++){ 
         for(int j = 0 ; j < content[i].length; j++){ 
            String text = content[i][j]; 
            contentStream.beginText(); 
            contentStream.moveTextPositionByAmount(textx,texty); 
            contentStream.drawString(text); 
            contentStream.endText(); 
            textx += colWidth; 
         } 
        
         texty-=rowHeight; 
         textx = margin+cellMargin; 
      } 
   }  
   
   @Override 
   public Tutorial process(Tutorial item) throws Exception { 
      System.out.println("Processing..." + item); 
   
      // Creating PDF document object 
      PDDocument doc = PDDocument.load(new File("C:/Examples/test.pdf"));     
      
      // Creating a blank page 
      PDPage page = new PDPage(); 
      doc.addPage( page ); 
      PDPageContentStream contentStream =  new PDPageContentStream(doc, page);  
      
      String[][] content = {{"Id",""+item.getTutorial_id()},
      {"Title", item.getTutorial_title()}, 
      {"Authour", item.getTutorial_author()}, 
      {"Submission Date", item.getSubmission_date()}} ;  
      drawTable(page, contentStream, 700, 100, content);       
      
      contentStream.close(); 
      doc.save("C:/Examples/test.pdf" ); 
      System.out.println("Hello"); 
      return item; 
   }    
}

TutorialFieldSetMapper.java

A continuación se muestra la clase ReportFieldSetMapper que establece los datos en la clase Tutorial.

import org.springframework.batch.item.file.mapping.FieldSetMapper; 
import org.springframework.batch.item.file.transform.FieldSet; 
import org.springframework.validation.BindException;  

public class TutorialFieldSetMapper implements FieldSetMapper<Tutorial> { 
   
   @Override 
   public Tutorial mapFieldSet(FieldSet fieldSet) throws BindException {   
      // instantiating the Tutorial class 
      Tutorial tutorial = new Tutorial(); 
   
      // Setting the fields from XML 
      tutorial.setTutorial_id(fieldSet.readInt(0));   
      tutorial.setTutorial_title(fieldSet.readString(1)); 
      tutorial.setTutorial_author(fieldSet.readString(2)); 
      tutorial.setTutorial_icon(fieldSet.readString(3)); 
      tutorial.setTutorial_description(fieldSet.readString(4));   
      return tutorial;  
   }  
}

Tutorial.java

Lo siguiente es el Tutorialclase. Es una clase simple consetter y getter métodos.

public class Tutorial { 
   private int tutorial_id; 
   private String tutorial_author; 
   private String tutorial_title; 
   private String submission_date; 
   private String tutorial_icon; 
   private String tutorial_description;   
   
   @Override 
   public String toString() { 
      return " [id=" + tutorial_id + ", author=" + tutorial_author  
         + ", title=" + tutorial_title + ", date=" + submission_date + ", icon =" 
         +tutorial_icon +", description = "+tutorial_description+"]"; 
   }  
   
   public int getTutorial_id() { 
      return tutorial_id; 
   }  
   
   public void setTutorial_id(int tutorial_id) { 
      this.tutorial_id = tutorial_id; 
   }  
   
   public String getTutorial_author() { 
      return tutorial_author; 
   }  
   
   public void setTutorial_author(String tutorial_author) { 
      this.tutorial_author = tutorial_author; 
   }  
   
   public String getTutorial_title() { 
      return tutorial_title; 
   } 
   
   public void setTutorial_title(String tutorial_title) { 
      this.tutorial_title = tutorial_title; 
   }  
   
   public String getSubmission_date() { 
      return submission_date; 
   }  
   
   public void setSubmission_date(String submission_date) { 
      this.submission_date = submission_date; 
   }  
   
   public String getTutorial_icon() { 
      return tutorial_icon; 
   }  
   
   public void setTutorial_icon(String tutorial_icon) { 
      this.tutorial_icon = tutorial_icon; 
   }  
   
   public String getTutorial_description() { 
      return tutorial_description; 
   }  
   
   public void setTutorial_description(String tutorial_description) { 
      this.tutorial_description = tutorial_description; 
   } 
}

App.java

A continuación se muestra el código que inicia el proceso por lotes. En esta clase, lanzaremos la aplicación Batch ejecutando JobLauncher.

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

Al ejecutar esta aplicación, producirá el siguiente resultado.

May 05, 2017 4:39:22 PM org.springframework.context.support.ClassPathXmlApplicationContext 
prepareRefresh 
INFO: Refreshing org[email protected]306a30c7: 
startup date [Fri May 05 16:39:22 IST 2017]; root of context hierarchy 
May 05, 2017 4:39:23 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 
May 05, 2017 4:39:32 PM org.springframework.batch.core.job.SimpleStepHandler handleStep 
INFO: Executing step: [step1] 
Processing... [id=1001, author=Sanjay, title=Learn Java, date=06-05-2007, 
icon =https://www.tutorialspoint.com/java/images/java-mini-logo.jpg, 
description = Java is a high-level programming language originally developed by Sun Microsystems 
and released in 1995. Java runs on a variety of platforms. 
This tutorial gives a complete understanding of Java.');] 
Hello 
Processing.. [id=1002, author=Abdul S, title=Learn MySQL, date=19-04-2007, 
icon =https://www.tutorialspoint.com/mysql/images/mysql-mini-logo.jpg, 
description = MySQL is the most popular Open Source Relational SQL database management system. 
MySQL is one of the best RDBMS being used for developing web-based software applications. 
This tutorial will give you quick start with MySQL and make you comfortable with MySQL programming.] 
Hello 
Processing... [id=1003, author=Krishna Kasyap, title=Learn JavaFX, date=06-072017, 
icon =https://www.tutorialspoint.com/javafx/images/javafx-mini-logo.jpg,
description = JavaFX is a Java library used to build Rich Internet Applications. 
The applications developed using JavaFX can run on various devices 
such as Desktop Computers, Mobile Phones, TVs, Tablets, etc. 
This tutorial, discusses all the necessary elements of JavaFX 
that are required to develop effective Rich Internet Applications] 
Hello 
May 05, 2017 4:39:36 PM 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

Si verifica el details.tutorial tabla en la base de datos, le mostrará el siguiente resultado:

tutorial _id tutorial _author tutorial _title día de entrega tutorial _icon tutorial _description
1001 Sanjay Aprende Java 06-05-2007 https: //www.tutorials point.com / java / images / java-mini-logo.jpg Java es un lenguaje de programación de alto nivel desarrollado originalmente por Sun Microsystems y lanzado en 1995. Java se ejecuta en una variedad de plataformas. Este tutorial proporciona una comprensión completa de Java.
1002 Abdul S Aprenda MySQL 19-04-2007 https: // www. tutorialspoint.com / mysql / images /mysql-minilogo.jpg MySQL es el sistema de gestión de bases de datos SQL relacional de código abierto más popular. MySQL es uno de los mejores RDBMS que se utilizan para desarrollar aplicaciones de software basadas en la web. Este tutorial le dará un inicio rápido con MySQL y lo hará sentir cómodo con la programación MySQL.
1003 Aprenda JavaFX Krishna Kasyap 06-07-2017 https: // www. tutorialspoint.com / javafx / images / javafx-minilogo.jpg MySQL es el sistema de gestión de bases de datos SQL relacional de código abierto más popular. MySQL es uno de los mejores RDBMS que se utilizan para desarrollar aplicaciones de software basadas en la web. Este tutorial le dará un inicio rápido con MySQL y lo hará sentir cómodo con la programación MySQL.

Esto generará un PDF con los registros de cada página como se muestra a continuación.

En este capítulo, crearemos una aplicación Spring Batch simple que usa un lector CSV y un escritor XML.

Reader - el reader que estamos usando en la aplicación es FlatFileItemReader para leer datos de los archivos CSV.

A continuación se muestra el archivo CSV de entrada que estamos usando en esta aplicación. Este documento contiene registros de datos que especifican detalles como la identificación del tutorial, el autor del tutorial, el título del tutorial, la fecha de envío, el icono del tutorial y la descripción del tutorial.

1001, "Sanjay", "Learn Java", 06/05/2007 
1002, "Abdul S", "Learn MySQL", 19/04/2007 
1003, "Krishna Kasyap", "Learn JavaFX", 06/07/2017

Writer - El escritor que estamos usando en la aplicación es StaxEventItemWriter para escribir los datos en un archivo XML.

Processor - El procesador que estamos usando en la aplicación es un procesador personalizado que simplemente imprime los registros leídos del archivo CSV.

jobConfig.xml

A continuación se muestra el archivo de configuración de nuestra aplicación Spring Batch de muestra. En este archivo, definiremos el trabajo y los pasos. Además de estos, también definimos los beans para ItemReader, ItemProcessor y ItemWriter. (Aquí, los asociamos con las clases respectivas y pasamos los valores de las propiedades requeridas para configurarlos).

<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" 
   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 = "cvsFileItemReader" writer = "xmlItemWriter" 
               processor = "itemProcessor" commit-interval = "10"> 
            </batch:chunk> 
         </batch:tasklet> 
      </batch:step> 
   </batch:job>  
 
   <bean id = "cvsFileItemReader" 
      class = "org.springframework.batch.item.file.FlatFileItemReader">  
      <property name = "resource" value = "classpath:resources/report.csv" /> 
      <property name = "lineMapper"> 
         <bean 
            class = "org.springframework.batch.item.file.mapping.DefaultLineMapper"> 
            <property name = "lineTokenizer"> 
               <bean    
                  class = "org.springframework.batch.item.file.transform.DelimitedLineTokenizer"> 
                  <property name = "names" value = "tutorial_id, 
                     tutorial_author, Tutorial_title, submission_date" /> 
               </bean> 
            </property> 
      
            <property name = "fieldSetMapper"> 
               <bean class = "ReportFieldSetMapper" /> 
            </property> 
         </bean> 
      </property> 
   </bean>  
   
   <bean id = "xmlItemWriter" 
      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 = "tutorials" /> 
   </bean>  
 
   <bean id = "reportMarshaller" 
      class = "org.springframework.oxm.jaxb.Jaxb2Marshaller">
      <property name = "classesToBeBound"> 
         <list> 
            <value>Tutorial</value> 
         </list> 
      </property> 
   </bean> 
</beans>

Context.xml

Lo siguiente es el context.xmlde nuestra aplicación Spring Batch. En este archivo, definiremos los beans como repositorio de trabajos, lanzador de trabajos y administrador de transacciones.

<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.ResourcelessTransactionManager" />  
   <bean id = "jobLauncher" 
      class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
      <property name = "jobRepository" ref = "jobRepository" /> 
   </bean>  
   
   <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

A continuación se muestra la clase Procesador. En esta clase, escribimos el código de procesamiento en la aplicación. Aquí, estamos imprimiendo el contenido de cada registro.

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

TutorialFieldSetMapper.java

A continuación se muestra la clase TutorialFieldSetMapper que establece los datos en la clase Tutorial.

import org.springframework.batch.item.file.mapping.FieldSetMapper; 
import org.springframework.batch.item.file.transform.FieldSet; 
import org.springframework.validation.BindException;  

public class TutorialFieldSetMapper implements FieldSetMapper<Tutorial> {  

   @Override 
   public Tutorial mapFieldSet(FieldSet fieldSet) throws BindException {  
      
      //Instantiating the report object  
      Tutorial tutorial = new Tutorial(); 
       
      //Setting the fields  
      tutorial.setTutorial_id(fieldSet.readInt(0)); 
      tutorial.setTutorial_author(fieldSet.readString(1)); 
      tutorial.setTutorial_title(fieldSet.readString(2)); 
      tutorial.setSubmission_date(fieldSet.readString(3)); 
       
      return tutorial; 
   } 
}

Clase Tutorial.java

Lo siguiente es el Tutorialclase. Es una clase Java simple consetter y gettermétodos. En esta clase, usamos anotaciones para asociar los métodos de esta clase con las etiquetas del archivo XML.

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

@XmlRootElement(name = "tutorial") 
public class Tutorial {  
   private int tutorial_id; 
   private String tutorial_author; 
   private String tutorial_title;
   private 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; 
   } 
   
   @Override 
   public String toString() { 
      return "  [Tutorial id=" + tutorial_id + ", 
         Tutorial Author=" + tutorial_author  + ", 
         Tutorial Title=" + tutorial_title + ", 
         Submission Date=" + submission_date + "]"; 
   } 
}

App.java

A continuación se muestra el código que inicia el proceso por lotes. En esta clase, lanzaremos la aplicación por lotes ejecutando JobLauncher.

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

Al ejecutar esta aplicación, producirá el siguiente resultado.

May 08, 2017 10:10:12 AM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 
INFO: Refreshing 
org[email protected]3d646c37: startup date 
[Mon May 08 10:10:12 IST 2017]; root of context hierarchy 
May 08, 2017 10:10:12 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 
May 08, 2017 10:10:15 AM org.springframework.jdbc.datasource.init.ScriptUtils executeSqlScript 
INFO: Executing step: [step1] 
Processing...  [Tutorial id=1001, Tutorial Author=Sanjay, 
Tutorial Title=Learn Java, Submission Date=06/05/2007] 
Processing...  [Tutorial id=1002, Tutorial Author=Abdul S, 
Tutorial Title=Learn MySQL, Submission Date=19/04/2007] 
Processing...  [Tutorial id=1003, Tutorial Author=Krishna Kasyap, 
Tutorial Title=Learn JavaFX, Submission Date=06/07/2017] 
May 08, 2017 10:10:21 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

Esto generará un archivo XML con el siguiente contenido.

<?xml version = "1.0" encoding = "UTF-8"?> 
<tutorials> 
   <tutorial tutorial_id = "1001"> 
      <submission_date>06/05/2007</submission_date> 
      <tutorial_author>Sanjay</tutorial_author> 
      <tutorial_title>Learn Java</tutorial_title> 
   </tutorial> 
   
   <tutorial tutorial_id = "1002"> 
      <submission_date>19/04/2007</submission_date> 
      <tutorial_author>Abdul S</tutorial_author> 
      <tutorial_title>Learn MySQL</tutorial_title> 
   </tutorial> 
   
   <tutorial tutorial_id = "1003"> 
      <submission_date>06/07/2017</submission_date>
      <tutorial_author>Krishna Kasyap</tutorial_author> 
      <tutorial_title>Learn JavaFX</tutorial_title> 
   </tutorial> 
</tutorials>

En este capítulo, crearemos una aplicación Spring Batch que usa un lector MySQL y un escritor XML.

Reader - El lector que estamos usando en la aplicación es JdbcCursorItemReader para leer datos de la base de datos MySQL.

Supongamos que hemos creado una tabla en la base de datos MySQL como se muestra a continuación:

CREATE TABLE details.xml_mysql( 
   person_id int(10) NOT NULL, 
   sales VARCHAR(20), 
   qty int(3), 
   staffName VARCHAR(20), 
   date VARCHAR(20) 
);

Supongamos que hemos insertado los siguientes registros en él.

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 - El escritor que estamos usando en la aplicación es StaxEventItemWriter para escribir los datos en el archivo XML.

Processor - El procesador que estamos usando en la aplicación es un procesador personalizado que simplemente imprime los registros leídos del archivo CSV.

jobConfig.xml

A continuación se muestra el archivo de configuración de nuestra aplicación Spring Batch de muestra. En este archivo, definiremos el Trabajo y los Pasos. Además de estos, también definimos los beans para ItemReader, ItemProcessor y ItemWriter. (Aquí, los asociamos con sus respectivas clases y pasamos los valores de las propiedades requeridas para configurarlos).

<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

Lo siguiente es el context.xmlde nuestra aplicación Spring Batch. En este archivo, definiremos los beans como repositorio de trabajos, lanzador de trabajos y administrador de transacciones.

<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

A continuación se muestra la clase Procesador. En esta clase, escribimos el código de procesamiento en la aplicación. Aquí, estamos imprimiendo el contenido de cada registro.

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

Lo siguiente es el TutorialRowMapper clase que establece los datos en el Tutorial clase.

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

Lo siguiente es el Tutorialclase. Es una clase Java simple consetter y gettermétodos. En esta clase, usamos anotaciones para asociar los métodos de esta clase con las etiquetas del archivo 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

A continuación se muestra el código que inicia el proceso por lotes. En esta clase, lanzaremos la aplicación Batch ejecutando JobLauncher.

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

Al ejecutar esta aplicación, producirá el siguiente resultado.

May 08, 2017 11:32:06 AM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 
INFO: Refreshing org[email protected]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

Esto generará un archivo XML con el siguiente contenido.

<?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>

En este capítulo, crearemos una aplicación Spring Batch que usa un lector MySQL y un Flatfile Escritor (.txt).

Reader - El lector que estamos usando en la aplicación es JdbcCursorItemReader para leer datos de la base de datos MySQL.

Suponga que hemos creado una tabla en la base de datos MySQL como se muestra a continuación.

CREATE TABLE details.xml_mysql( 
   person_id int(10) NOT NULL, 
   sales VARCHAR(20), 
   qty int(3), 
   staffName VARCHAR(20), 
   date VARCHAR(20) 
);

Supongamos que hemos insertado los siguientes registros en él.

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 - El escritor que estamos usando en la aplicación es FlatFileItemWriter escribir los datos en flatfile (.TXT).

Processor - El procesador que estamos usando en la aplicación es un procesador personalizado que simplemente imprime los registros leídos del archivo CSV.

jobConfig.xml

A continuación se muestra el archivo de configuración de nuestra aplicación Spring Batch de muestra. En este archivo, definiremos el Trabajo y los Pasos. Además de estos, también definimos los beans para ItemReader, ItemProcessor y ItemWriter. (Aquí, los asociamos con las clases respectivas y pasamos los valores de las propiedades requeridas para configurarlos).

<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 = "tutorial" class = "Tutorial" scope = "prototype" /> 
   <bean id = "itemProcessor" class = "CustomItemProcessor" />  
   
   <batch:job id = "helloWorldJob"> 
      <batch:step id = "step1"> 
         <batch:tasklet> 
            <batch:chunk reader = "mysqlItemReader" 
               writer = "flatFileItemWriter" processor = "itemProcessor" 
               commit-interval = "10"> 
            </batch:chunk> 
         </batch:tasklet> 
      </batch:step> 
   </batch:job> 
         
   <bean id = "mysqlItemReader" 
      class = "org.springframework.batch.item.database.JdbcCursorItemReader" > 
      <property name = "dataSource" ref = "dataSource" /> 
      <property name = "sql" value = "select * from details.tutorialsdata" /> 
      <property name = "rowMapper">  
         <bean class = "TutorialRowMapper" /> 
      </property> 
   </bean>
   
   <bean id = "flatFileItemWriter" 
      class = " org.springframework.batch.item.file.FlatFileItemWriter">      
      <property name = "resource" value = "file:target/outputfiles/employee_output.txt"/> 
      <property name = "lineAggregator"> 
         <bean class = " org.springframework.batch.item.file.transform.PassThroughLineAggregator"/> 
      </property> 
   </bean> 
</beans>

Context.xml

Lo siguiente es el context.xmlde nuestra aplicación Spring Batch. En este archivo, definiremos los beans como repositorio de trabajos, lanzador de trabajos y administrador de transacciones.

<beans xmlns = "http://www.springframework.org/schema/beans" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:jdbc = "http://www.springframework.org/schema/jdbc" 
   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.ResourcelessTransactionManager" />  
   
   <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> 
    
   <bean id = "jobLauncher"  
      class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
      <property name = "jobRepository" ref = "jobRepository" /> 
   </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

A continuación se muestra la clase Procesador. En esta clase, escribimos el código de procesamiento en la aplicación. Aquí, estamos imprimiendo el contenido de cada registro.

import org.springframework.batch.item.ItemProcessor;  

// Implementing the ItemProcessor interface 
public class CustomItemProcessor implements ItemProcessor<Tutorial, Tutorial> {  
 
   @Override 
   public Tutorial process(Tutorial item) throws Exception { 
      System.out.println("Processing..." + item); 
      return item; 
   } 
}

TutorialRowMapper.java

Lo siguiente es el TutorialRowMapper clase que establece los datos en el Tutorial clase.

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

Tutorial.java

Lo siguiente es el Tutorialclase. Es una clase Java simple consetter y gettermétodos. En esta clase, usamos anotaciones para asociar los métodos de esta clase con las etiquetas del archivo XML.

public class Tutorial { 
   private int tutorial_id; 
   private String tutorial_title; 
   private String tutorial_author; 
   private String submission_date; 
  
   public int getTutorial_id() { 
      return tutorial_id; 
   }  
   
   public void setTutorial_id(int tutorial_id) { 
      this.tutorial_id = tutorial_id; 
   }
   
   public String getTutorial_title() { 
      return tutorial_title; 
   }   
 
   public void setTutorial_title(String tutorial_title) { 
      this.tutorial_title = tutorial_title; 
   }  
   
   public String getTutorial_author() { 
      return tutorial_author; 
   }  
 
   public void setTutorial_author(String tutorial_author) { 
      this.tutorial_author = tutorial_author; 
   }  
 
   public String getSubmission_date() { 
      return submission_date; 
   }  
   public void setSubmission_date(String submission_date) { 
      this.submission_date = submission_date; 
   }  
 
   @Override 
   public String toString() { 
      return " [id=" + tutorial_id + ", title=" + 
      tutorial_title                      + ", 
      author=" + tutorial_author + ", date=" + 
      submission_date + "]"; 
   } 
}

App.java

A continuación se muestra el código que inicia el proceso por lotes. En esta clase, lanzaremos la aplicación Batch ejecutando JobLauncher.

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

Al ejecutar esta aplicación, producirá el siguiente resultado.

May 09, 2017 5:44:48 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 
INFO: Refreshing org.springframework.context.support.ClassPathXml
[email protected]: startup date [Tue May 
09 17:44:48 IST 2017]; root of context hierarchy 
May 09, 2017 5:44:48 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions  
May 09, 2017 5:44:56 PM org.springframework.batch.core.launch.support.SimpleJobLauncher run 
INFO: Job: [FlowJob: [name=helloWorldJob]] launched 
with the following parameters: [{}] 
May 09, 2017 5:44:56 PM org.springframework.batch.core.job.SimpleStepHandler handleStep 
INFO: Executing step: [step1] 
Processing...Report [id=101, title=Learn Java, author=Sanjay, date=06-05-2007] 
Processing...Report [id=102, title=Learn MySQL, author=Abdul S, date=19-04-2007] 
Processing...Report [id=103, title=Learn JavaFX, author=Krishna Kasyap, date=0607-2017] 
May 09, 2017 5:44:57 PM org.springframework.batch.core.launch.support.SimpleJobLauncher run 
INFO: Job: [FlowJob: [name=helloWorldJob]] completed with the following parameters: 
[{}] and the following status: [COMPLETED] 
Hello 
Exit Status : COMPLETED

Esto generará un .txt archivo con el siguiente contenido.

Report [id=101, title=Learn Java, author=Sanjay, date=06-05-2007] 
Report [id=102, title=Learn MySQL, author=Abdul S, date=19-04-2007] 
Report [id=103, title=Learn JavaFX, author=Krishna Kasyap, date=06-07-2017]