Spring Boot + Spring Batch + MySQL Hello World Example
What is Batch Processing
Let us first have a look at what is meant by Batch Processing and where it is used. Batch Processing is a very old concept. Older than Spring Framework itself. Batch processing can be defined as processing of large amount of data in an automated way without any external intervention. Let us take a look at some scenarios where Batch Processing is used -- Every day in the evening you receive a statement of the stocks you have traded. After the market closes for the day, a batch job runs that processes all the day's transactions and creates this statement which is then mailed you.
- Big Data requires to process a large amount of data. This data can be provided to Big Data using Batch Jobs.
- During Migration large amount of data is to be moved from one physical location to another.
Video Tutorial
What is Spring Batch
Spring Batch is an open source framework for batch processing. It is a lightweight, comprehensive solution designed to enable the development of robust batch applications, which are often found in modern enterprise systems. Spring Batch builds upon the POJO-based development approach of the Spring Framework.Before we begin the implementation let us understand some concepts of Spring Batch. Any work that we want to accomplish using Spring Batch is called a Job. So suppose we want to create an End of Day Stock Transaction Statement, then this will be called a Spring Batch Job. To complete this Job we break it's implementation into Steps. For example for creation of End of Day Statement Job can be broken into -
- Fetch all the Buys for a particular customer
- Fetch all the Sells for a particular customer
- Perform some calculation
- Send it to the customer
In Spring Batch, Steps can be of two types-
- Tasklet based step- Tasklets are used when we want to perform a single task within a step
-
Chunk based step - Chunks read a chunk of data and then perform 3 tasks on this chunk -
- Item Reader
- Item Processor
- Item Writer
Implementation
In this example we will be creating a Spring Batch Application which will have a single tasklet that simply prints hello world to the screen.Technology Stack
We will be making use of-- Java 1.8
- Spring Boot
- Spring Batch
- Spring JDBC
- Maven
- MySQL
The pom.xml will be as follows-
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.codeusingjava</groupId> <artifactId>boot-batch</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-batch</artifactId> </dependency> </dependencies> </project>Create the Spring Boot Bootstrap class as follows-
package com.codeusingjava; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootBatch { public static void main(String[] args) { SpringApplication.run(SpringBootBatch.class, args); } }Create the Spring Batch Configuration file. This class we willbe making use of the annotation EnableBatchProcessing. The @EnableBatchProcessing annotation enables Spring Batch features and the needed dependencies.
package com.codeusingjava.config; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.StepContribution; 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.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @EnableBatchProcessing public class SpringBatchConfig { @Autowired public JobBuilderFactory jobBuilderFactory; @Autowired public StepBuilderFactory stepBuilderFactory; @Bean public Step helloWorldStep() { return stepBuilderFactory.get("helloWorldStep").tasklet(new Tasklet() { public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception { System.out.println("Hello World Step"); return RepeatStatus.FINISHED; } }).build(); } @Bean public Job helloWorldJob() { return jobBuilderFactory.get("helloWorldJob").start(helloWorldStep()).build(); } }If we now run the application we get the following exception
It is because we need to specify some database for storing the Job metadata. We will be making use of MySQL database for this.
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.codeusingjava</groupId> <artifactId>boot-batch</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-batch</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies> </project>We now define the mysql properties in the application.properties configuration file. Do remember to set the spring.batch.initialize-schema to Always. If not done the application will not start as the Spring Batch Job Metadata tables do not get created by default.
spring.datasource.url=jdbc:mysql://localhost/bootbatch?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false spring.datasource.username=root spring.datasource.password=root spring.datasource.platform=mysql spring.datasource.initialization-mode=always spring.batch.initialize-schema=ALWAYSNow start the application-
In the mysql database we can see the following tables are created in the bootbatch db-
The tables are as follows-
Go to Batch Instance Table-
Go to Batch Execution Table-