This topic introduces how to build an application by using the SpringBatch framework and OceanBase Database. It also covers the use of the application for fundamental database operations, including table creation, data insertion, data query, and other basic operations.
Prerequisites
- You have installed OceanBase Database.
- You have installed JDK 1.8 and Maven.
- You have installed IntelliJ IDEA.
Note
The tool used to run the sample code in this topic is IntelliJ IDEA 2021.3.2 (Community Edition). You can also choose a tool of your preference to run the sample code.
Procedure
Note
The steps outlined in this topic are for the Windows environment. If you are using a different operating system or compiler, the steps may vary slightly.
- Obtain the connection string of OceanBase Database.
- Import the
java-oceanbase-springbatchproject into IntelliJ IDEA. - Modify the database connection information in the
java-oceanbase-springbatchproject. - Run the
java-oceanbase-springbatchproject.
Step 1: Obtain the connection string of OceanBase Database
Contact the deployment personnel or administrator of OceanBase Database to obtain the corresponding database connection string.
obclient -hxx.xx.xx.xx -P2883 -uroot@sys#cluster -p**** -AFill in the URL below based on the OceanBase Database that has been deployed.
Note
The URL is required in the
application.propertiesfile.jdbc:oceanbase://host:port/schema_name?user=$user_name&password=$password&characterEncoding=utf-8Parameter description:
host: the IP address for connecting to OceanBase Database. For connection through ODP, use the IP address of an ODP. For direct connection, use the IP address of an OBServer node.port: the port for connecting to OceanBase Database. For connection through ODP, the default value is2883, which can be customized when ODP is deployed. For direct connection, the default value is2881, which can be customized when OceanBase Database is deployed.schema_name: the name of the schema to be accessed.user_name: the username specified after the-uparameter. The value of the username is in the format of username@tenant name#cluster name or username@SERVICE:service name. When you use the format username@tenant name#cluster name, the default tenant issysand the default administrator isroot. The cluster name can be omitted when you connect directly to the database, but it is required when you connect through ODP.password: the password of the account.characterEncoding: the character encoding.
For more information about URL parameters, see Database URL.
Step 2: Import the java-oceanbase-springbatch project into IntelliJ IDEA
Start IntelliJ IDEA and choose File > Open....

In the Open File or Project window, select the project files and click OK to import the files.
IntelliJ IDEA automatically recognizes the files and displays the directory structure, file list, module list, dependency relationships, and other details of the project in the Project window. The Project window is usually positioned on the left side of the IntelliJ IDEA interface and is generally open by default. If the Project window is closed, you can reopen it by choosing View > Tool Windows > Project in the menu bar or by using the shortcut Alt + 1.
Note
When you import a project using IntelliJ IDEA, it will automatically detect the pom.xml file in the project, download the required dependency libraries based on the described dependencies in the file, and add them to the project.
View the project.

Step 3: Modify the database connection information in the java-oceanbase-springbatch project
Modify the database connection information in the application.properties file based on the information obtained in Step 1: Obtain the connection string of OceanBase Database.
Here is an example:
- The name of the database driver is:
com.mysql.cj.jdbc.Driver. - The IP address of the OBServer node is
10.10.10.1. - The port is 2881.
- The name of the database to be accessed is
test. - The tenant account is
root@mysql001, wheremysql001is a MySQL user tenant created in OceanBase Database, androotis the username of themysql001tenant. - The password is
******.
Sample code:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:oceanbase://10.10.10.1:2881/test?characterEncoding=utf-8
spring.datasource.username=root@mysql001
spring.datasource.password=******
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.batch.job.enabled=false
logging.level.org.springframework=INFO
logging.level.com.example=DEBUG
Step 4: Run the java-oceanbase-springbatch project
Run the
AddDescPeopleWriterTest.javafile.- In the project structure, locate the
AddDescPeopleWriterTest.javafile under src > test > java. - In the toolbar, choose Run > Run... > AddDescPeopleWriterTest.testWrite or simply click the green triangle in the upper-right corner to run it.
- In the console of IDEA, view the project logs and output results.
Data in the people_desc table: PeopleDESC [name=John, age=25, desc=This is John with age 25] PeopleDESC [name=Alice, age=30, desc=This is Alice with age 30] Batch Job execution completed.- In the project structure, locate the
Run the
AddPeopleWriterTest.javafile.- In the project structure, locate the
AddPeopleWriterTest.javafile under src > test > java. - In the toolbar, choose Run > Run... > AddPeopleWriterTest.testWrite or simply click the green triangle in the upper-right corner to run it.
- In the console of IDEA, view the project logs and output results.
Data in the people table: People [name=zhangsan, age=27] People [name=lisi, age=35] Batch Job execution completed.- In the project structure, locate the
FAQ
1. Connection timeout
If a connection timeout occurs, you can specify the connection timeout parameter in the JDBC URL:
jdbc:mysql://host:port/database?connectTimeout=30000&socketTimeout=60000
2. Character set
To ensure correct character encoding, set the character set parameter in the JDBC URL:
jdbc:mysql://host:port/database?characterEncoding=utf8&useUnicode=true
3. SSL connection
To establish an SSL connection with OceanBase Database, add the following parameter to the JDBC URL:
jdbc:mysql://host:port/database?useSSL=true&requireSSL=true
4. Special characters in account name or password
If the username or password contains special characters such as #, URL-encode it:
String encodedPassword = URLEncoder.encode(password, "UTF-8");
Notice
When you use MySQL Connector/J 8.x, make sure that the account name and password do not contain the number sign (#). Otherwise, a connection error may occur.
Project code introduction
Click java-oceanbase-springbatch to download the project code, which is a compressed package named java-oceanbase-springbatch.
After decompressing it, you will find a folder named java-oceanbase-springbatch. The directory structure is as follows:
│ pom.xml
│
├─.idea
│
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─oceanbase
│ │ │ └─example
│ │ │ └─batch
│ │ │ │──BatchApplication.java
│ │ │ │
│ │ │ ├─config
│ │ │ │ └─BatchConfig.java
│ │ │ │
│ │ │ ├─model
│ │ │ │ ├─People.java
│ │ │ │ └─PeopleDESC.java
│ │ │ │
│ │ │ ├─processor
│ │ │ │ └─AddPeopleDescProcessor.java
│ │ │ │
│ │ │ └─writer
│ │ │ ├─AddDescPeopleWriter.java
│ │ │ └─AddPeopleWriter.java
│ │ │
│ │ └─resources
│ │ └─application.properties
│ │
│ └─test
│ └─java
│ └─com
│ └─oceanbase
│ └─example
│ └─batch
│ ├─config
│ │ └─BatchConfigTest.java
│ │
│ ├─processor
│ │ └─AddPeopleDescProcessorTest.java
│ │
│ └─writer
│ ├─AddDescPeopleWriterTest.java
│ └─AddPeopleWriterTest.java
│
└─target
File description:
pom.xml: the configuration file of the Maven project, which contains the dependencies, plugins, and build details of the project..idea: the directory used by the Integrated Development Environment (IDE) to store project-related configuration information.src: a directory that is generally used to store the source code of the project.main: the directory that stores the main source code and resource files.java: the directory that stores the Java source code.com.oceanbase.example.batch: the package name.BatchApplication.java: the entry class of the application, which contains the main method of the application.config: the folder that stores the configuration classes of the application.BatchConfig.java: the configuration class of the application, which is used to configure the attributes and behaviors of the application.model: the folder that stores the model classes of the application.People.java: the personnel data model class.PeopleDESC.java: the personnel DESC data model class.processor: the folder that stores the processor classes of the application.AddPeopleDescProcessor.java: the processor class that is used to add personnel DESC information.writer: the folder that stores the writer classes of the application.AddDescPeopleWriter.java: the writer class that is used to write personnel DESC information.AddPeopleWriter.java: the writer class that is used to write personnel information.resources: the resource folder that stores the configuration files and other static resource files of the application.application.properties: the configuration file of the application, which is used to configure the attributes of the application.test: the directory that stores the test code and resource files.BatchConfigTest.java: the test class of the application configuration class.AddPeopleDescProcessorTest.java: the test class of the processor for adding personnel DESC information.AddDescPeopleWriterTest.java: the test class of the writer for writing personnel DESC information.AddPeopleWriterTest.java: the test class of the writer for writing personnel information.target: the directory that stores compiled class files and JAR packages.
Introduction to pom.xml
Note
If you just want to verify the sample, you can use the default code without modification. You can also modify the pom.xml file based on your needs.
The content of the pom.xml configuration file is as follows:
Declaration statement.
Declare this file to be an XML file that uses XML version
1.0and character encodingUTF-8.Sample code:
<?xml version="1.0" encoding="UTF-8"?>Configure namespaces and the POM model version.
- Use
xmlnsto specify the POM namespace ashttp://maven.apache.org/POM/4.0.0. - Use
xmlns:xsito specify the XML namespace ashttp://www.w3.org/2001/XMLSchema-instance. - Use
xsi:schemaLocationto specify the POM namespace ashttp://maven.apache.org/POM/4.0.0, and the location of the POM XSD file ashttps://maven.apache.org/xsd/maven-4.0.0.xsd. - Use the
<modelVersion>element to specify the POM model version used by the POM file as4.0.0.
Sample code:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> </project>- Use
Configure the parent information.
- Use
<groupId>to specify the parent identifier asorg.springframework.boot. - Use
<artifactId>to specify the parent dependency asspring-boot-starter-parent. - Use
<version>to specify the parent version as2.7.11. - Use
relativePathto indicate that the parent path is empty.
Sample code:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.11</version> <relativePath/> </parent>- Use
Configure basic information.
- Use
<groupId>to specify the project identifier ascom.oceanbase. - Use
<artifactId>to specify the project dependency asjava-oceanbase-springboot. - Use
<version>to specify the project version as0.0.1-SNAPSHOT. - Use
descriptionto describe the project asDemo project for Spring Batch.
Sample code:
<groupId>com.oceanbase</groupId> <artifactId>java-oceanbase-springboot</artifactId> <version>0.0.1-SNAPSHOT</version> <name>java-oceanbase-springbatch</name> <description>Demo project for Spring Batch</description>- Use
Configure the Java version.
Specify the Java version used by the project as 1.8.
Sample code:
<properties> <java.version>1.8</java.version> </properties>Configure core dependencies.
Specify the group as
org.springframework.bootand the name asspring-boot-starter. With this dependency, you can access the component dependencies supported by Spring Boot by default, including Web, data processing, security, and test features.Sample code:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>Specify the group as
org.springframework.bootand the name asspring-boot-starter-jdbc. With this dependency, you can access the JDBC features provided by Spring Boot, such as connection pools and data source configurations.Sample code:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>Specify the group as
org.springframework.boot, the name asspring-boot-starter-test, and the scope astest. With this dependency, you can access the test framework and tools provided by Spring Boot, such as JUnit, Mockito, and Hamcrest.Sample code:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>Specify the group as
com.oceanbase, the name asoceanbase-client, and the version as2.4.12. With this dependency, you can access the client features provided by OceanBase, such as connection, query, and transaction.Sample code:
<dependency> <groupId>com.oceanbase</groupId> <artifactId>oceanbase-client</artifactId> <version>2.4.12</version> </dependency>Specify the group as
org.springframework.boot, the name asspring-boot-starter-batch, and the scope astest. With this dependency, you can access the batch processing feature provided by Spring Boot.Sample code:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-batch</artifactId> </dependency>Specify the group as
org.springframework.boot, the name asspring-boot-starter-data-jpa, and the scope astest. With this dependency, you can access the necessary dependencies and configurations for data access using JPA. Spring Boot Starter Data JPA is a Spring Boot starter.Sample code:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>Specify the group as
org.apache.tomcat, the name astomcat-jdbc, and the scope astest. With this dependency, you can access the JDBC connection pool feature provided by Tomcat, including connection pool configuration, connection acquisition and release, and connection management.Sample code:
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> </dependency>Specify the test architecture as
junit, the name asjunit, and the version as4.10, and the scope astest. With this dependency, you can configure JUnit unit test dependencies.Sample code:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency>Specify the group as
javax.activation, the name asjavax.activation-api, and the version as1.2.0. With this dependency, you can introduce the Java Activation Framework (JAF) library.Sample code:
<dependency> <groupId>javax.activation</groupId> <artifactId>javax.activation-api</artifactId> <version>1.2.0</version> </dependency>Specify the group as
jakarta.persistence, the name asjakarta.persistence-api, and the version as2.2.3. With this dependency, you can configure the Jakarta Persistence API dependency.Sample code:
<dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>2.2.3</version> </dependency>
Configure the Maven plugin.
Specify the group as
org.springframework.bootand the name asspring-boot-maven-plugin. This plugin is used to package a Spring Boot application into an executable JAR or WAR file.Sample code:
Introduction to application.properties
The application.properties file is used to configure database connections and other related settings, such as the database driver, connection URL, username, and password. It also includes configurations for Java Persistence API (JPA) and Spring Batch, as well as settings for log levels.
Database connection configuration.
- The
spring.datasource.driverparameter is set tocom.mysql.cj.jdbc.Driverto connect to OceanBase Database. - The
spring.datasource.urlparameter specifies the URL for connecting to the database. - The
spring.datasource.usernameparameter specifies the username for connecting to the database. - The
spring.datasource.passwordparameter specifies the password for connecting to the database.
Sample code:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:oceanbase://host:port/schema_name?characterEncoding=utf-8 spring.datasource.username=user_name spring.datasource.password=******- The
JPA configuration.
- The
spring.jpa.show-sqlparameter specifies whether to log SQL statements. If set totrue, SQL statements are logged. - The
spring.jpa.hibernate.ddl-autoparameter specifies the DDL operation behavior of Hibernate. Here, it is set toupdate, indicating that the database schema will be automatically updated when the application starts.
Sample code:
spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update- The
Spring Batch configuration:
The
spring.batch.job.enabledparameter specifies whether to enable Spring Batch jobs. Here, it is set tofalse, indicating that batch processing jobs will not be automatically executed.Sample code:
spring.batch.job.enabled=falseNote
In Spring Batch, the
spring.batch.job.enabledattribute controls the execution behavior of batch jobs.- If
spring.batch.job.enabled=true(the default value), all defined batch jobs will automatically run when the Spring Boot application starts. This means that Spring Batch will automatically discover and execute all defined jobs upon application startup. - If
spring.batch.job.enabled=false, automatic execution of batch jobs is disabled. This is typically used in development or test environments, or when you want to manually control job execution. If set tofalse, jobs will not automatically run upon application startup. Instead, you can manually trigger them using other methods such as REST interfaces or command lines.
spring.batch.job.enabled=falsehelps you avoid automatically running jobs upon application startup, providing greater flexibility over when batch jobs are executed.- If
Log configuration:
- The
logging.level.org.springframeworkparameter specifies the log level for the Spring framework asINFO. - The
logging.level.com.exampleparameter specifies the log level for custom application code asDEBUG.
Sample code:
logging.level.org.springframework=INFO logging.level.com.example=DEBUG- The
Introduction to BatchApplication.java
The BatchApplication.java file is the entry file of the Spring Boot application.
The code in the BatchApplication.java file consists of the following parts:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
SpringApplicationclass: used to start the Spring Boot application.SpringBootApplicationannotation: used to mark the class as the entry point of the Spring Boot application.
Sample code:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;Define the
BatchApplicationclass.Mark the
BatchApplicationclass with the@SpringBootApplicationannotation to indicate that it is the entry point of the Spring Boot application. TheBatchApplicationclass defines a staticmainmethod as the entry point of the application. In this method, it uses theSpringApplication.runmethod to start the Spring Boot application. It also defines a method namedrunBatchJobto run batch processing jobs.Sample code:
@SpringBootApplication public class BatchApplication { public static void main(String[] args) { SpringApplication.run(BatchApplication.class, args); } public void runBatchJob() { } }
Introduction to BatchConfig.java
The BatchConfig.java file is used to configure the components of a batch processing job, such as steps, readers, processors, and writers.
The code in the BatchConfig.java file mainly includes the following sections:
Reference other classes and interfaces.
Declare the current file to contain the following interfaces and classes:
Peopleclass: used to store the personnel information read from the database.PeopleDESCclass: used to store the description information of the personnel information after conversion or processing.AddPeopleDescProcessorclass: used to convert the readPeopleobject into aPeopleDESCobject. This class is the implementation class of theItemProcessorinterface.AddDescPeopleWriterclass: used to write thePeopleDESCobject to the target location. This class is the implementation class of theItemWriterinterface.Jobinterface: represents a batch processing job.Stepinterface: represents a step in a job.EnableBatchProcessingannotation: a configuration annotation in Spring Batch for enabling and configuring the Spring Batch processing feature.JobBuilderFactoryclass: used to create and configure jobs.StepBuilderFactoryclass: used to create and configure steps.RunIdIncrementerclass: the run ID (Run ID) auto-incrementer of Spring Batch. It is used to increase the run ID each time when the job is run.ItemProcessorinterface: used to process or convert read items.ItemReaderinterface: used to read items from the data source.ItemWriterinterface: used to write the processed or converted items to a specified target location.JdbcCursorItemReaderclass: used to read data from the database and return a cursor result set.Autowiredannotation: used for dependency injection.Beanannotation: used for creating and configuring beans.ComponentScanannotation: used to specify the package or class to be scanned for components.Configurationannotation: used to mark a class as a configuration class.EnableAutoConfigurationannotation: used to enable the automatic configuration of Spring Boot.SpringBootApplicationannotation: used to mark a class as the entry of a Spring Boot application.DataSourceinterface: used to represent a database connection.
Sample code:
import com.oceanbase.example.batch.model.People; import com.oceanbase.example.batch.model.PeopleDESC; import com.oceanbase.example.batch.processor.AddPeopleDescProcessor; import com.oceanbase.example.batch.writer.AddDescPeopleWriter; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.database.JdbcCursorItemReader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.BeanPropertyRowMapper; import javax.sql.DataSource;Define the
BatchConfigclass.This is a simple Spring Batch job. It defines the methods for reading, processing, and writing data, and encapsulates these methods into a job. By using the annotations and automatic configuration feature of Spring Batch, you can create component instances by configuring the
@Beanmethods in the configuration class, and use these component instances instep1to read, process, and write data.- Use
@Configurationto indicate that this class is a configuration class. - Use
@EnableBatchProcessingto enable the Spring Batch processing feature. This annotation will automatically create necessarybeanssuch asJobRepositoryandJobLauncher. - Use
@SpringBootApplicationto indicate the main class of a Spring Boot application. It is the startup point of the Spring Boot application. - Use
@ComponentScanto specify the package to be scanned for components. This tells Spring to scan and register all components in this package and its subpackages. - Use
@EnableAutoConfigurationto enable the automatic configuration of the infrastructure of a Spring Boot application.
Sample code:
@Configuration @EnableBatchProcessing @SpringBootApplication @ComponentScan("com.oceanbase.example.batch.writer") @EnableAutoConfiguration public class BatchConfig { }Define the
@Autowiredannotation.Use the
@Autowiredannotation to injectJobBuilderFactory,StepBuilderFactory, andDataSourceinto the member variables of theBatchConfigclass.JobBuilderFactoryis a factory class for creating and configuring jobs, andStepBuilderFactoryis a factory class for creating and configuring steps.DataSourceis an interface for obtaining a database connection.Sample code:
@Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Autowired private DataSource dataSource;Define the
@Beanannotation.Use the
@Beanannotation to define several methods for creating the readers, processors, writers, steps, and jobs of a batch processing job.Use the
peopleReadermethod to create anItemReadercomponent instance. This component reads thePeopleobject data from the database by usingJdbcCursorItemReader. Set the data source todataSource, set theRowMapperto map database rows toPeopleobjects, and set the SQL query statement toSELECT * FROM people.Use the
addPeopleDescProcessormethod to create anItemProcessorcomponent instance. This component processes thePeopleobject by usingAddPeopleDescProcessorand returns thePeopleDESCobject.Use the
addDescPeopleWritermethod to create anItemWritercomponent instance. This component writes thePeopleDESCobject to the target location by usingAddDescPeopleWriter.Use the
step1method to create aStepcomponent instance. The step is namedstep1. UsestepBuilderFactory.getto obtain the step builder. Set the reader to theItemReadercomponent, set the processor to theItemProcessorcomponent, set the writer to theItemWritercomponent, set thechunksize to10, and then callbuildto build and return the configuredStep.Use the
importJobmethod to create aJobcomponent instance. The job is namedimportJob. UsejobBuilderFactory.getto obtain the job builder. Set the incrementer toRunIdIncrementer. Set the initial step of the jobflowtoStep. Then callbuildto build and return the configuredJob.Sample code:
@Bean public ItemReader<People> peopleReader() { JdbcCursorItemReader<People> reader = new JdbcCursorItemReader<>(); reader.setDataSource((javax.sql.DataSource) dataSource); reader.setRowMapper(new BeanPropertyRowMapper<>(People.class)); reader.setSql("SELECT * FROM people"); return reader; } @Bean public ItemProcessor<People, PeopleDESC> addPeopleDescProcessor() { return new AddPeopleDescProcessor(); } @Bean public ItemWriter<PeopleDESC> addDescPeopleWriter() { return new AddDescPeopleWriter(); } @Bean public Step step1(ItemReader<People> reader, ItemProcessor<People, PeopleDESC> processor, ItemWriter<PeopleDESC> writer) { return stepBuilderFactory.get("step1") .<People, PeopleDESC>chunk(10) .reader(reader) .processor(processor) .writer(writer) .build(); } @Bean public Job importJob(Step step1) { return jobBuilderFactory.get("importJob") .incrementer(new RunIdIncrementer()) .flow(step1) .end() .build(); }
- Use
People.java file introduction
The People.java file creates a data model for the People class, representing information about a person. This class contains two private member variables, name and age, along with their corresponding getter and setter methods. The toString method is overridden to print the object's information. The name variable indicates the person's name, and the age variable indicates the person's age. The getter and setter methods are used to obtain and set the values of these attributes.
The purpose of this class is to provide a way to store and transmit data for the input and output of batch jobs. During the read and write operations in batch processing, People objects are used to store data. Data is set using the setter methods and obtained using the getter methods.
Sample code:
public class People {
private String name;
private int age;
// getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "People [name=" + name + ", age=" + age + "]";
}
// Getters and setters
}
PeopleDESC.java file introduction
The PeopleDESC.java file creates a data model for the PeopleDESC class, which is used to represent information about personnel. The PeopleDESC class has four attributes: name, age, desc, and id, which respectively indicate the name, age, description, and identifier of a person. This class contains getter and setter methods for accessing and setting the attribute values. The toString method is overridden to return a string representation of the class, including the name, age, and description.
Similar to the People class, the PeopleDESC class is also used to store and transmit data for the input and output of batch jobs.
Sample code:
public class PeopleDESC {
private String name;
private int age;
private String desc;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "PeopleDESC [name=" + name + ", age=" + age + ", desc=" + desc + "]";
}
}
AddPeopleDescProcessor.java file introduction
The AddPeopleDescProcessor.java file defines a class named AddPeopleDescProcessor that implements the ItemProcessor interface. This class is used to convert People objects into PeopleDESC objects.
The code in the AddPeopleDescProcessor.java file is divided into several parts:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
Peopleclass: used to store personnel information read from the database.PeopleDESCclass: used to store descriptive information after the personnel information is converted or processed.ItemProcessorinterface: used to process or convert read items.
Sample code:
import com.oceanbase.example.batch.model.People; import com.oceanbase.example.batch.model.PeopleDESC; import org.springframework.batch.item.ItemProcessor;Define the
AddPeopleDescProcessorclass.The
AddPeopleDescProcessorclass that implements theItemProcessorinterface is used to convertPeopleobjects intoPeopleDESCobjects. This implements the logic for processing input data in batch jobs.In the
processmethod of this class, aPeopleDESCobject nameddescis created first. Then, the attributes (nameandage) of thePeopleobject passed in through theitemparameter are obtained, and these attributes are set to thedescobject. Additionally, thedescattribute of thedescobject is also assigned a value. The assignment logic generates a description based on the attributes of thePeopleobject. Finally, the processedPeopleDESCobject is returned.Sample code:
public class AddPeopleDescProcessor implements ItemProcessor<People, PeopleDESC> { @Override public PeopleDESC process(People item) throws Exception { PeopleDESC desc = new PeopleDESC(); desc.setName(item.getName()); desc.setAge(item.getAge()); desc.setDesc("This is " + item.getName() + " with age " + item.getAge()); return desc; } }
Introduction to AddDescPeopleWriter.java
The AddDescPeopleWriter.java file implements the AddDescPeopleWriter class that implements the ItemWriter interface for writing People objects to a database.
The code in the AddDescPeopleWriter.java file consists of the following sections:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
PeopleDESC: a class used to store descriptions after the information of the personnel is converted or processed.ItemWriter: an interface used to write processed or converted items to a specified target location.Autowired: an annotation used for dependency injection.JdbcTemplate: a class that provides methods for executing SQL statements.List: an interface used for operating on the query result set.
Sample code:
import com.oceanbase.example.batch.model.PeopleDESC; import org.springframework.batch.item.ItemWriter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import java.util.List;Define the
AddDescPeopleWriterclass.Use the
@Autowiredannotation to automatically inject aJdbcTemplateinstance, which is used to perform database operations when writing data.Sample code:
@Autowired private JdbcTemplate jdbcTemplate;In the
writemethod, traverse theList<? extends PeopleDESC>that is passed in, and sequentially obtain eachPeopleDESCobject. First, execute the SQL statementDROP TABLE people_descto delete a table namedpeople_descif it exists. Then, execute the SQL statementCREATE TABLE people_desc (id INT PRIMARY KEY, name VARCHAR2(255), age INT, description VARCHAR2(255))to create a table namedpeople_descwith four columns:id,name,age, anddescription. Next, use the SQL statementINSERT INTO people_desc (id, name, age, description) VALUES (?, ?, ?, ?)to insert the attribute values of eachPeopleDESCobject into thepeople_desctable.Sample code:
@Override public void write(List<? extends PeopleDESC> items) throws Exception { // Drop the table if it exists. jdbcTemplate.execute("DROP TABLE people_desc"); // Statement for creating the table. String createTableSql = "CREATE TABLE people_desc (id INT PRIMARY KEY, name VARCHAR2(255), age INT, description VARCHAR2(255))"; jdbcTemplate.execute(createTableSql); for (PeopleDESC item : items) { String sql = "INSERT INTO people_desc (id, name, age, description) VALUES (?, ?, ?, ?)"; jdbcTemplate.update(sql, item.getId(), item.getName(), item.getAge(), item.getDesc()); } }
Introduction to AddPeopleWriter.java
The AddPeopleWriter.java file implements the AddDescPeopleWriter class that implements the ItemWriter interface for writing PeopleDESC objects to the database.
The code in the AddPeopleWriter.java file consists of the following sections:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
Peopleclass: used to store personnel information read from the database.ItemWriterinterface: used to write processed or converted items to a specified target location.Autowiredannotation: used for dependency injection.JdbcTemplateclass: provides methods for executing SQL statements.Componentannotation: used to mark the class as a Spring component.Listinterface: used for operating on the query result set.
Sample code:
import com.oceanbase.example.batch.model.People; import org.springframework.batch.item.ItemWriter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import java.util.List;Define the
AddPeopleWriterclass.Use the
@Autowiredannotation to automatically inject aJdbcTemplateinstance for database operations when writing data.Sample code:
@Autowired private JdbcTemplate jdbcTemplate;In the
writemethod, traverse theList<? extends People>that is passed in, and sequentially take out eachPeopleobject. First, execute the SQL statementDROP TABLE peopleto delete a table namedpeopleif it exists. Then, execute the SQL statementCREATE TABLE people (name VARCHAR2(255), age INT)to create a table namedpeople, which contains thenameandagecolumns. Next, use the SQL statementINSERT INTO people (name, age) VALUES (?, ?)to insert the attribute values of eachPeopleobject into thepeopletable.Sample code:
@Override public void write(List<? extends People> items) throws Exception { // Delete the table if it exists. jdbcTemplate.execute("DROP TABLE people"); // Statement for creating the table. String createTableSql = "CREATE TABLE people (name VARCHAR2(255), age INT)"; jdbcTemplate.execute(createTableSql); for (People item : items) { String sql = "INSERT INTO people (name, age) VALUES (?, ?)"; jdbcTemplate.update(sql, item.getName(), item.getAge()); } }
Introduction to BatchConfigTest.java
The BatchConfigTest.java file is a class that uses JUnit for testing the configuration of Spring Batch jobs.
The code in the BatchConfigTest.java file consists of the following sections:
Reference other classes and interfaces.
The current file contains the following interfaces and classes:
Assert: a class used to assert test results.Test: an annotation used to mark test methods.RunWith: an annotation used to specify the test runner.Job: an interface that represents a batch job.JobExecution: a class used to represent the execution of a batch job.JobParameters: a class used to represent the parameters of a batch job.JobParametersBuilder: a class used to build the parameters of a batch job.JobLauncher: an interface used to start a batch job.Autowired: an annotation used to perform dependency injection.SpringBootTest: an annotation used to specify the test class as a Spring Boot test.SpringRunner: a class used to specify the test runner as SpringRunner.
Sample code:
import org.junit.Assert; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.batch.runtime.BatchStatus; import java.util.UUID;Define the
BatchConfigTestclass.You can perform Spring Boot integration tests by using the
SpringBootTestannotation and theSpringRunnerrunner. In thetestJobmethod, a batch job is started by using theJobLauncherTestUtilsutility class, and the job's execution status is verified by using assertions.Use the
@Autowiredannotation to automatically inject theJobLauncherTestUtilsinstance.Sample code:
@Autowired private JobLauncherTestUtils jobLauncherTestUtils;Use the
@Testannotation to mark thetestJobmethod as a test method. In this method, aJobParametersobject is first created, and then thejobLauncherTestUtils.launchJobmethod is used to start the batch job. TheAssert.assertEqualsmethod is used to assert that the job's execution status isCOMPLETED.Sample code:
@Test public void testJob() throws Exception { JobParameters jobParameters = new JobParametersBuilder() .addString("jobParam", "paramValue") .toJobParameters(); JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters); Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); }Use the
@Autowiredannotation to automatically inject theJobLauncherinstance.Sample code:
@Autowired private JobLauncher jobLauncher;Use the
@Autowiredannotation to automatically inject theJobinstance.Sample code:
@Autowired private Job job;Define an inner class named
JobLauncherTestUtilsto assist in starting batch jobs. In this class, define alaunchJobmethod for starting batch jobs. In this method, thejobLauncher.runmethod is used to start the job, and the job's execution result is returned.Sample code:
private class JobLauncherTestUtils { public JobExecution launchJob(JobParameters jobParameters) throws Exception { return jobLauncher.run(job, jobParameters); } }
Introduction to AddPeopleDescProcessorTest.java
The AddPeopleDescProcessorTest.java file is a class that uses JUnit for testing the Spring Batch job configuration.
The code in the AddPeopleDescProcessorTest.java file consists of the following sections:
Reference other classes and interfaces.
The current file contains the following interfaces and classes:
People: a class used to store personnel information read from the database.PeopleDESC: a class used to store descriptions after the personnel information is converted or processed.Assert: a class used to verify whether the expected result and actual result are consistent.Test: an annotation used to mark a test method.RunWith: an annotation used to specify the test runner.Autowired: an annotation used to perform dependency injection.SpringBootTest: an annotation used to specify the test class as a Spring Boot test.SpringRunner: a class used to specify the test runner as SpringRunner.
Sample code:
import com.oceanbase.example.batch.model.People; import com.oceanbase.example.batch.model.PeopleDESC; import org.junit.Assert; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;Define the
AddPeopleDescProcessorTestclass.Use the
SpringBootTestannotation and SpringRunner runner to perform an integrated test of a Spring Boot application.Use the
@Autowiredannotation to automatically inject anAddPeopleDescProcessorinstance.Sample code:
@Autowired private AddPeopleDescProcessor processor;Use the
@Testannotation to mark thetestProcessmethod as a test method. In this method, aPeopleobject is created first, and then theprocessor.processmethod is used to process this object, and the result is assigned to aPeopleDESCobject.Sample code:
@Test public void testProcess() throws Exception { People people = new People(); people.setName("John"); people.setAge(25); PeopleDESC desc = processor.process(people); }
Introduction to AddDescPeopleWriterTest.java
The AddDescPeopleWriterTest.java file is a class that uses JUnit for testing the write logic of AddDescPeopleWriter.
The code in the AddDescPeopleWriterTest.java file consists of the following sections:
Reference other classes and interfaces.
The current file contains the following interfaces and classes:
PeopleDESC: a class used to store the descriptions converted or processed from the personnel information.Assert: a class used to assert the test results.Test: an annotation used to mark test methods.RunWith: an annotation used to specify the test runner.Autowired: an annotation used to perform dependency injection.SpringBootTest: an annotation used to specify the test class as a Spring Boot test.JdbcTemplate: a class that provides methods for executing SQL statements.SpringRunner: a class used to specify the test runner as SpringRunner.ArrayList: a class used to create an empty list.List: an interface used to operate on the query result set.
Sample code:
import com.oceanbase.example.batch.model.PeopleDESC; import org.junit.Assert; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List;Define the
AddDescPeopleWriterTestclass.Use the
SpringBootTestannotation and theSpringRunnerrunner to perform an integrated test of Spring Boot.Inject instances using
@Autowired. Use the@Autowiredannotation to automatically inject theAddPeopleDescProcessorandJdbcTemplateinstances.Sample code:
@Autowired private AddDescPeopleWriter writer; @Autowired private JdbcTemplate jdbcTemplate;Use
@Testto test the insertion and output of data. Use the@Testannotation to mark thetestWritemethod as a test method. In this method, first create an emptypeopleDescListlist and add twoPeopleDESCobjects to the list. Then, call thewritemethod ofwriterto write the data in the list to the database. Next, usejdbcTemplateto execute a query statement to obtain the data in thepeople_desctable, and use assertion statements to verify the correctness of the data. Finally, output the query result to the console and output a message indicating that the job has been completed.Insert data into the
people_desctable. First, create an empty list ofPeopleDESCobjects namedpeopleDescList. Then, create twoPeopleDESCobjects nameddesc1anddesc2, and set their attribute values. Adddesc1anddesc2to thepeopleDescListlist. Next, call thewritemethod ofwriterto write the objects inpeopleDescListto thepeople_desctable in the database. Then, useJdbcTemplateto execute a query statementSELECT COUNT(*) FROM people_descto obtain the number of records in thepeople_desctable and assign the result to the variablecount. Finally, useAssert.assertEqualsto verify whether the value ofcountis equal to2.Sample code:
List<PeopleDESC> peopleDescList = new ArrayList<>(); PeopleDESC desc1 = new PeopleDESC(); desc1.setId(1); desc1.setName("John"); desc1.setAge(25); desc1.setDesc("This is John with age 25"); peopleDescList.add(desc1); PeopleDESC desc2 = new PeopleDESC(); desc2.setId(2); desc2.setName("Alice"); desc2.setAge(30); desc2.setDesc("This is Alice with age 30"); peopleDescList.add(desc2); writer.write(peopleDescList); String selectSql = "SELECT COUNT(*) FROM people_desc"; int count = jdbcTemplate.queryForObject(selectSql, Integer.class); Assert.assertEquals(2, count);Output data in the
people_desctable. UseJdbcTemplateto execute a query statementSELECT * FROM people_descand process the query result using alambdaexpression. In thelambdaexpression, use methods such asrs.getIntandrs.getStringto obtain the field values in the result set and set the field values to a newly createdPeopleDESCobject. Add each newly createdPeopleDESCobject to a result list namedresultDesc. Then, print a prompt messagepeople_desc table data:. Traverse eachPeopleDESCobject in theresultDesclist using aforloop, and useSystem.out.printlnto print the content of each object. Finally, print a message indicating that the job has been completed.Sample code:
List<PeopleDESC> resultDesc = jdbcTemplate.query("SELECT * FROM people_desc", (rs, rowNum) -> { PeopleDESC desc = new PeopleDESC(); desc.setId(rs.getInt("id")); desc.setName(rs.getString("name")); desc.setAge(rs.getInt("age")); desc.setDesc(rs.getString("description")); return desc; }); System.out.println("people_desc table data:"); for (PeopleDESC desc : resultDesc) { System.out.println(desc); } // Output the information after the job is completed. System.out.println("Batch Job execution completed.");
Introduction to AddPeopleWriterTest.java
The AddPeopleWriterTest.java file is a class that uses JUnit for testing the write logic of the AddPeopleWriterTest class.
The code in the AddPeopleWriterTest.java file consists of the following sections:
Reference other classes and interfaces.
Declare the following interfaces and classes in the current file:
Peopleclass: a class used to store the person information read from the database.Testannotation: an annotation used to mark test methods.RunWithannotation: an annotation used to specify the test runner.Autowiredannotation: an annotation used to perform dependency injection.SpringBootApplicationannotation: an annotation used to mark the class as the entry point of a Spring Boot application.SpringBootTestannotation: an annotation used to specify the test class as a Spring Boot test.ComponentScanannotation: an annotation used to specify the package or class to be scanned for components.JdbcTemplateclass: a class that provides methods for executing SQL statements.SpringRunnerclass: a class used to specify the test runner asSpringRunner.ArrayListclass, used to create an empty list.Listinterface: an interface used to operate on the query result set.
Sample code:
import com.oceanbase.example.batch.model.People; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List;Define the
AddPeopleWriterTestclass.Use the
SpringBootTestannotation andSpringRunnerrunner to perform an integration test of a Spring Boot application, and use the@ComponentScanannotation to specify the package path to be scanned.Use
@Autowiredto inject instances. Use the@Autowiredannotation to automatically inject theaddPeopleWriterandJdbcTemplateinstances.Sample code:
@Autowired private AddPeopleWriter addPeopleWriter; @Autowired private JdbcTemplate jdbcTemplate;Use
@Testto test the insertion and output of data.Insert data into the
peopletable. First, create an emptyPeopleobject list namedpeopleList. Then, create twoPeopleobjects namedperson1andperson2, and set their name and age attributes. Next, add the twoPeopleobjects to thepeopleListlist. After that, call thewritemethod ofaddPeopleWriter, passpeopleListas the method parameter, and write thePeopleobjects inpeopleListto the database.Sample code:
List<People> peopleList = new ArrayList<>(); People person1 = new People(); person1.setName("zhangsan"); person1.setAge(27); peopleList.add(person1); People person2 = new People(); person2.setName("lisi"); person2.setAge(35); peopleList.add(person2); addPeopleWriter.write(peopleList);Output the data in the
peopletable. First, use theJdbcTemplateto execute a query statementSELECT * FROM peopleand process the query result using alambdaexpression. In thelambdaexpression, use thers.getStringandrs.getIntmethods to obtain the field values in the query result set and set the field values to a newly createdPeopleobject. Add each newly createdPeopleobject to a result list namedresult. Next, print a prompt messagepeople table data:. Then, use aforloop to traverse eachPeopleobject in theresultlist and useSystem.out.printlnto print the content of each object. Finally, print a message indicating that the job has completed execution.Sample code:
List<People> result = jdbcTemplate.query("SELECT * FROM people", (rs, rowNum) -> { People person = new People(); person.setName(rs.getString("name")); person.setAge(rs.getInt("age")); return person; }); System.out.println("people table data:"); for (People person : result) { System.out.println(person); } // Print a message indicating the completion of job execution System.out.println("Batch Job execution completed.");
Complete code
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.oceanbase</groupId>
<artifactId>java-oceanbase-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>java-oceanbase-springbatch</name>
<description>Demo project for Spring Batch</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.oceanbase</groupId>
<artifactId>oceanbase-client</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>2.2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
#configuration database
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:oceanbase://host:port/schema_name?characterEncoding=utf-8
spring.datasource.username=user_name
spring.datasource.password=
# JPA
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
# Spring Batch
spring.batch.job.enabled=false
#
logging.level.org.springframework=INFO
logging.level.com.example=DEBUG
package com.oceanbase.example.batch;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BatchApplication {
public static void main(String[] args) {
SpringApplication.run(BatchApplication.class, args);
}
public void runBatchJob() {
}
}
package com.oceanbase.example.batch.config;
import com.oceanbase.example.batch.model.People;
import com.oceanbase.example.batch.model.PeopleDESC;
import com.oceanbase.example.batch.processor.AddPeopleDescProcessor;
import com.oceanbase.example.batch.writer.AddDescPeopleWriter;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import javax.sql.DataSource;
//import javax.activation.DataSource;
@Configuration
@EnableBatchProcessing
@SpringBootApplication
@ComponentScan("com.oceanbase.example.batch.writer")
@EnableAutoConfiguration
public class BatchConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private DataSource dataSource;// Use the default dataSource provided by Spring Boot auto-configuration.
@Bean
public ItemReader<People> peopleReader() {
JdbcCursorItemReader<People> reader = new JdbcCursorItemReader<>();
reader.setDataSource((javax.sql.DataSource) dataSource);
reader.setRowMapper(new BeanPropertyRowMapper<>(People.class));
reader.setSql("SELECT * FROM people");
return reader;
}
@Bean
public ItemProcessor<People, PeopleDESC> addPeopleDescProcessor() {
return new AddPeopleDescProcessor();
}
@Bean
public ItemWriter<PeopleDESC> addDescPeopleWriter() {
return new AddDescPeopleWriter();
}
@Bean
public Step step1(ItemReader<People> reader, ItemProcessor<People, PeopleDESC> processor,
ItemWriter<PeopleDESC> writer) {
return stepBuilderFactory.get("step1")
.<People, PeopleDESC>chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
@Bean
public Job importJob(Step step1) {
return jobBuilderFactory.get("importJob")
.incrementer(new RunIdIncrementer())
.flow(step1)
.end()
.build();
}
}
package com.oceanbase.example.batch.model;
public class People {
private String name;
private int age;
// getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "People [name=" + name + ", age=" + age + "]";
}
// Getters and setters
}
package com.oceanbase.example.batch.model;
public class PeopleDESC {
private String name;
private int age;
private String desc;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "PeopleDESC [name=" + name + ", age=" + age + ", desc=" + desc + "]";
}
}
package com.oceanbase.example.batch.processor;
import com.oceanbase.example.batch.model.People;
import com.oceanbase.example.batch.model.PeopleDESC;
import org.springframework.batch.item.ItemProcessor;
public class AddPeopleDescProcessor implements ItemProcessor<People, PeopleDESC> {
@Override
public PeopleDESC process(People item) throws Exception {
PeopleDESC desc = new PeopleDESC();
desc.setName(item.getName());
desc.setAge(item.getAge());
desc.setDesc("This is " + item.getName() + " with age " + item.getAge());
return desc;
}
}
package com.oceanbase.example.batch.writer;
import com.oceanbase.example.batch.model.PeopleDESC;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class AddDescPeopleWriter implements ItemWriter<PeopleDESC> {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void write(List<? extends PeopleDESC> items) throws Exception {
// Drop the table if it exists.
jdbcTemplate.execute("DROP TABLE people_desc");
// Create the table.
String createTableSql = "CREATE TABLE people_desc (id INT PRIMARY KEY, name VARCHAR2(255), age INT, description VARCHAR2(255))";
jdbcTemplate.execute(createTableSql);
for (PeopleDESC item : items) {
String sql = "INSERT INTO people_desc (id, name, age, description) VALUES (?, ?, ?, ?)";
jdbcTemplate.update(sql, item.getId(), item.getName(), item.getAge(), item.getDesc());
}
}
}
package com.oceanbase.example.batch.writer;
import com.oceanbase.example.batch.model.People;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class AddPeopleWriter implements ItemWriter<People> {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void write(List<? extends People> items) throws Exception {
// Drop the table if it exists.
jdbcTemplate.execute("DROP TABLE people");
// Create the table.
String createTableSql = "CREATE TABLE people (name VARCHAR2(255), age INT)";
jdbcTemplate.execute(createTableSql);
for (People item : items) {
String sql = "INSERT INTO people (name, age) VALUES (?, ?)";
jdbcTemplate.update(sql, item.getName(), item.getAge());
}
}
}
package com.oceanbase.example.batch.config;
import com.oceanbase.example.batch.writer.AddDescPeopleWriter;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import javax.batch.runtime.BatchStatus;
import java.util.UUID;
@RunWith(SpringRunner.class)
@SpringBootTest
public class BatchConfigTest {
@Test
public void testJob() throws Exception {
JobParameters jobParameters = new JobParametersBuilder()
.addString("jobParam", UUID.randomUUID().toString())
.toJobParameters();
JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils();
JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters);
Assert.assertEquals(BatchStatus.COMPLETED.toString(), jobExecution.getStatus().toString());
}
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job job;
private class JobLauncherTestUtils {
public JobExecution launchJob(JobParameters jobParameters) throws Exception {
return jobLauncher.run(job, jobParameters);
}
}
}
package com.oceanbase.example.batch.processor;
import com.oceanbase.example.batch.model.People;
import com.oceanbase.example.batch.model.PeopleDESC;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class AddPeopleDescProcessorTest {
@Autowired
private AddPeopleDescProcessor processor;
@Test
public void testProcess() throws Exception {
People people = new People();
// people.setName("John");
// people.setAge(25);
PeopleDESC desc = processor.process(people);
// Assert.assertEquals("John", desc.getName());
// Assert.assertEquals(25, desc.getAge());
// Assert.assertEquals("This is John with age 25", desc.getDesc());
}
}
package com.oceanbase.example.batch.writer;
import com.oceanbase.example.batch.model.PeopleDESC;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class AddDescPeopleWriterTest {
@Autowired
private AddDescPeopleWriter writer;
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testWrite() throws Exception {
// Insert data into the people_desc table.
List<PeopleDESC> peopleDescList = new ArrayList<>();
PeopleDESC desc1 = new PeopleDESC();
desc1.setId(1);
desc1.setName("John");
desc1.setAge(25);
desc1.setDesc("This is John with age 25");
peopleDescList.add(desc1);
PeopleDESC desc2 = new PeopleDESC();
desc2.setId(2);
desc2.setName("Alice");
desc2.setAge(30);
desc2.setDesc("This is Alice with age 30");
peopleDescList.add(desc2);
writer.write(peopleDescList);
String selectSql = "SELECT COUNT(*) FROM people_desc";
int count = jdbcTemplate.queryForObject(selectSql, Integer.class);
Assert.assertEquals(2, count);
// Output data in the people_desc table.
List<PeopleDESC> resultDesc = jdbcTemplate.query("SELECT * FROM people_desc", (rs, rowNum) -> {
PeopleDESC desc = new PeopleDESC();
desc.setId(rs.getInt("id"));
desc.setName(rs.getString("name"));
desc.setAge(rs.getInt("age"));
desc.setDesc(rs.getString("description"));
return desc;
});
System.out.println("Data in the people_desc table:");
for (PeopleDESC desc : resultDesc) {
System.out.println(desc);
}
// Output the information after the job is executed.
System.out.println("Batch Job execution completed.");
}
}
package com.oceanbase.example.batch.writer;
import com.oceanbase.example.batch.model.People;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
@SpringBootApplication
@ComponentScan("com.oceanbase.example.batch.writer")
public class AddPeopleWriterTest {
@Autowired
private AddPeopleWriter addPeopleWriter;
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testWrite() throws Exception {
// Insert data into the people table.
List<People> peopleList = new ArrayList<>();
People person1 = new People();
person1.setName("zhangsan");
person1.setAge(27);
peopleList.add(person1);
People person2 = new People();
person2.setName("lisi");
person2.setAge(35);
peopleList.add(person2);
addPeopleWriter.write(peopleList);
// Query and output the result.
List<People> result = jdbcTemplate.query("SELECT * FROM people", (rs, rowNum) -> {
People person = new People();
person.setName(rs.getString("name"));
person.setAge(rs.getInt("age"));
return person;
});
System.out.println("Data in the people table:");
for (People person : result) {
System.out.println(person);
}
// Output the information after the job is executed.
System.out.println("Batch Job execution completed.");
}
}
References
For more information about OceanBase Connector/J, see OceanBase Connector/J.

Download the java-oceanbase-springbatch sample project