This topic introduces how to build an application by using the Spring Batch framework and OceanBase Database. It also covers the use of the application for fundamental database operations, including table creation, data insertion, and data query.
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), but you can also choose a tool that suits your personal preference to run the 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 OceanBase Database connection string.
- Import the
java-oceanbase-springbatchproject into IDEA. - Modify the database connection information in the
java-oceanbase-springbatchproject. - Run the
java-oceanbase-springbatchproject.
Step 1: Obtain the OceanBase Database connection string
Contact the deployment personnel or administrator of OceanBase Database to obtain the database connection string.
obclient -hxx.xx.xx.xx -P2883 -uroot@sys#cluster -p**** -AFill in the URL below based on the deployed OceanBase database.
Note
The URL here is required in the
application.propertiesfile.jdbc:oceanbase://host:port/schema_name?user=$user_name&password=$password&characterEncoding=utf-8Parameters in the URL are described as follows:
host: the IP address for connecting to OceanBase Database. For connection through OceanBase Database Proxy (ODP), this parameter is the IP address of an ODP. For direct connection, this parameter is 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 access.user_name: the tenant account. For connection through ODP, the tenant account can be in theusername@tenant name#cluster nameorcluster name:tenant name:usernameformat. For direct connection, the tenant account is in theusername@tenant nameformat.password: the account password.characterEncoding: the character encoding method.
For more information about URL parameters, see Database URL.
Step 2: Import the java-oceanbase-springbatch project into IDEA
Start IntelliJ IDEA and choose File > Open....

In the Open File or Project window that appears, select the corresponding project file and click OK to import the project file.
IntelliJ IDEA automatically identifies all types of files in the project. In the Project window, you can view the directory structure, list of files, list of modules, and dependencies of the project. The Project window is usually on the far left side in IntelliJ IDEA and is displayed by default. If the Project window is closed, you can choose View > Tool Windows > Project from the menu or use the Alt + 1 shortcut to open the window.
Note
When you use IntelliJ IDEA to import a project, IntelliJ IDEA automatically detects the
pom.xmlfile in the project, downloads the required libraries based on the dependencies defined in the file, and adds the libraries 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 OceanBase Database connection string.
Here is an example:
- The name of the database driver is
com.oceanbase.jdbc.Driver. - The IP address of the OBServer node is
10.10.10.1. - The port is 2881.
- The name of the schema to access is
sys. - The tenant account is
sys@xyoracle, wherexyoracleis a user tenant created in the Oracle mode of OceanBase Database, andsysis a username in thexyoracletenant. - The password is
******.
The sample code is as follows:
spring.datasource.driver-class-name=com.oceanbase.jdbc.Driver
spring.datasource.url=jdbc:oceanbase://10.10.10.1:2881/sys?characterEncoding=utf-8
spring.datasource.username=sys@xyoracle
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.- Find the
AddDescPeopleWriterTest.javafile under src > test > java in the project package. - Choose Run > Run... > AddDescPeopleWriterTest.testWrite in the menu bar or click the green triangle in the upper-right corner to run the file.
- View the logs and output of the project in the IDEA console.
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.- Find the
Run the
AddPeopleWriterTest.javafile.- Find the
AddDescPeopleWriterTest.javafile under src > test > java in the project package. - Choose Run > Run... > AddPeopleWriterTest.testWrite in the menu bar or click the green triangle in the upper-right corner to run the file.
- View the logs and output of the project in the IDEA console.
Data in the people table: People [name=zhangsan, age=27] People [name=lisi, age=35] Batch Job execution completed.- Find the
Project code introduction
Click java-oceanbase-springbatch to download the project code, which is a compressed file named java-oceanbase-springbatch.
Decompress the package to obtain a folder named java-oceanbase-springbatch. The directory is structured 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
Here is a breakdown of the files and directories:
pom.xml: the configuration file of the Maven project, which contains the dependencies, plug-ins, and build information of the project..idea: the directory used in the Integrated Development Environment (IDE) for storing project-related configurations.src: the directory for storing source code of the project.main: the directory for storing main source code and resource files.java: the directory for storing Java source code.com: the root directory for storing the Java package.oceanbase: the root directory for storing the project.example: the root directory for storing the project.batch: the main package of the project.BatchApplication.java: the entry class to the application, which contains the main method of the application.config: the configuration class folder that contains the configuration class of the application.BatchConfig.java: the configuration class of the application, which is used to configure some properties and behavior of the application.model: the model class folder that contains the data model classes of the application.People.java: the personnel data model class.PeopleDESC.java: the personnel DESC data model class.processor: the processor class folder that contains the processor class of the application.AddPeopleDescProcessor.java: the processor class that adds personnel DESC information.writer: the writer class folder that contains the writer classes of the application.AddDescPeopleWriter.java: the writer class that writes personnel DESC information.AddPeopleWriter.java: the writer class that writes personnel information.resources: the resource folder that contains the configuration file and other static resource files of the application.application.properties: the configuration file of the application, which is used to configure the properties of the application.test: the directory for storing the test code and resource files.BatchConfigTest.java: the test class for the configuration class of the application.AddPeopleDescProcessorTest.java: the test class for the processor class that adds personnel DESC information.AddDescPeopleWriterTest.java: the test class for the writer class that writes personnel DESC information.AddPeopleWriterTest.java: the test class for the writer class that writes personnel information.target: the directory for storing compiled class files and JAR packages.
Code in pom.xml
Note
If you just want to verify the sample project, use the default code without modification. You can also modify the pom.xml file as required based on the following instructions.
To configure the pom.xml file, perform the following steps:
Declare the file.
Declare the file to be an XML file that uses XML standard
1.0and character encodingUTF-8.The sample code is as follows:
<?xml version="1.0" encoding="UTF-8"?>Configure the namespaces and the POM model version.
- Use
xmlnsto specifyhttp://maven.apache.org/POM/4.0.0as the default XML namespace for the POM. - Use
xmlns:xsito specifyhttp://www.w3.org/2001/XMLSchema-instanceas the XML namespace for xsi-prefixed elements. - Use
xsi:schemaLocationto provide a mapping from the default XML namespace for the POM (http://maven.apache.org/POM/4.0.0) to the location of the POM's XML schema definition (XSD) file (https://maven.apache.org/xsd/maven-4.0.0.xsd). - Use
<modelVersion>to specify4.0.0as the model version used by the POM.
The sample code is 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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> </project>- Use
Configure parent project information.
- Use
<groupId>to specifyorg.springframework.bootas the ID of the parent project group. - Use
<artifactId>to specifyspring-boot-starter-parentas the ID of the parent project. - Use
<version>to specify2.7.11as the version of the parent project. - Use
<relativePath>to specify an empty path for the parent project.
The sample code is as follows:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.11</version> <relativePath/> </parent>- Use
Configure basic project information.
- Use
<groupId>to specifycom.oceanbaseas the ID of the project group. - Use
<artifactId>to specifyjava-oceanbase-springbootas the ID of the project. - Use
<version>to specify0.0.1-SNAPSHOTas the version of the project. - Use
<description>to describe the project asDemo project for Spring Batch.
The sample code is as follows:
<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 to use Java 1.8 for the project.
The sample code is as follows:
<properties> <java.version>1.8</java.version> </properties>Configure core dependencies.
Specify
org.springframework.bootas the ID of the group that the dependency belongs to, andspring-boot-starteras the dependency ID. This dependency contains default features provided by Spring Boot, such as web, data processing, security, and test.The sample code is as follows:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>Specify
org.springframework.bootas the ID of the group that the dependency belongs to, andspring-boot-starter-jdbcas the dependency ID. This dependency contains JDBC features provided by Spring Boot, such as the connection pool and data source configuration.The sample code is as follows:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>Specify
org.springframework.bootas the ID of the group that the dependency belongs to, andspring-boot-starter-testas the dependency ID. This dependency takes effect ontestand provides test frameworks and tools of Spring Boot, such as JUnit, Mockito, and Hamcrest.The sample code is as follows:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>Specify
com.oceanbaseas the ID of the group that the dependency belongs to,oceanbase-clientas the dependency ID, and2.4.3as the dependency version. This dependency allows the project to use the client features, such as connection, query, and transaction, provided by OceanBase.The sample code is as follows:
<dependency> <groupId>com.oceanbase</groupId> <artifactId>oceanbase-client</artifactId> <version>2.4.3</version> </dependency>Specify
org.springframework.bootas the ID of the group that the dependency belongs to, andspring-boot-starter-batchas the dependency ID. This dependency contains the batch processing feature provided by Spring Boot.The sample code is as follows:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-batch</artifactId> </dependency>Specify
org.springframework.bootas the ID of the group that the dependency belongs to, andspring-boot-starter-data-jpaas the dependency ID. This dependency contains necessary dependencies and configurations for JPA-based database accesses, and is a Spring Boot starter.The sample code is as follows:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>Specify
org.apache.tomcatas the ID of the group that the dependency belongs to, andtomcat-jdbcas the dependency ID. This dependency allows the application to use JDBC connection pool features provided by Tomcat, including connection pool configuration, connection acquisition and release, and connection management.The sample code is as follows:
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> </dependency>Specify
junitas the ID of the group that the dependency belongs to,junitas the dependency ID,4.10as the dependency version, andtestas the effective scope. This dependency allows the application to use JUnit.The sample code is as follows:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency>Specify
javax.activationas the ID of the group that the dependency belongs to,javax.activation-apias the dependency ID, and1.2.0as the dependency version. This dependency provides the Java Activation Framework (JAF) API.The sample code is as follows:
<dependency> <groupId>javax.activation</groupId> <artifactId>javax.activation-api</artifactId> <version>1.2.0</version> </dependency>Specify
jakarta.persistenceas the ID of the group that the dependency belongs to,jakarta.persistence-apias the dependency ID, and2.2.3as the dependency version. This dependency provides the Jakarta Persistence API.The sample code is as follows:
<dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>2.2.3</version> </dependency>
Configure the Maven plug-in.
Specify
org.springframework.bootas the ID of the group that the plug-in belongs to, andspring-boot-maven-pluginas the plug-in ID. This plug-in can be used to package Spring Boot applications as executable JAR packages or WAR packages, or directly run Spring Boot applications.The sample code is as follows:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
Code in application.properties
The application.properties file contains database connection configurations, such as the database driver, URL, username, and password. It also contains configurations related to the Java Persistence API (JPA), Spring Batch, and log level.
Configure the database connection.
- Use
spring.datasource.driverto specifycom.oceanbase.jdbc.Driveras the database driver for establishing a connection with OceanBase Database. - Use
spring.datasource.urlto specify the URL of the database. - Use
spring.datasource.usernameto specify the username for connecting to the database. - Use
spring.datasource.passwordto specify the password for connecting to the database.
The sample code is as follows:
spring.datasource.driver-class-name=com.oceanbase.jdbc.Driver spring.datasource.url=jdbc:oceanbase://host:port/schema_name?characterEncoding=utf-8 spring.datasource.username=user_name spring.datasource.password=******- Use
Configure the JPA.
- Use
spring.jpa.show-sqlto specify whether to display SQL statements in logs. The valuetruehere indicates that SQL statements are displayed in logs. - Use
spring.jpa.hibernate.ddl-autoto specify the DDL operation performed by Hibernate. The valueupdatehere indicates that Hibernate automatically updates the database schema when the application starts.
The sample code is as follows:
spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update- Use
Configure Spring Batch.
Use
spring.batch.job.enabledto specify whether to enable Spring Batch jobs. The valuefalsehere indicates that Spring Batch jobs are disabled.The sample code is as follows:
spring.batch.job.enabled=falseConfigure the log level.
- Use
logging.level.org.springframeworkto specifyINFOas the log level of the Spring framework. - Use
logging.level.com.exampleto specifyDEBUGas the log level for the custom code of the application.
The sample code is as follows:
logging.level.org.springframework=INFO logging.level.com.example=DEBUG- Use
Code in BatchApplication.java
The BatchApplication.java file is the entry file to the Spring Boot application.
To configure the BatchApplication.java file, perform the following steps:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
SpringApplicationclass: launches the Spring Boot application.SpringBootApplicationannotation: marks the class as the entry to the Spring Boot application.
The sample code is as follows:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;Define the
BatchApplicationclass.Use the
@SpringBootApplicationannotation to mark theBatchApplicationclass as the entry to the Spring Boot application. In theBatchApplicationclass, define a staticmainmethod as the entry to the program. In themainmethod, use theSpringApplication.runmethod to launch the Spring Boot application. Define a method namedrunBatchJobto run the batch job.The sample code is as follows:
@SpringBootApplication public class BatchApplication { public static void main(String[] args) { SpringApplication.run(BatchApplication.class, args); } public void runBatchJob() { } }
Code in BatchConfig.java
The BatchConfig.java file configures components such as the step, reader, processor, and writer for batch jobs.
To configure the BatchConfig.java file, perform the following steps:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
Peopleclass: stores personnel information read from the database.PeopleDESCclass: stores the description converted or processed from personnel information.AddPeopleDescProcessorclass: converts aPeopleobject to aPeopleDESCobject. This class implements theItemProcessorinterface.AddDescPeopleWriterclass: writes aPeopleDESCobject to a specified destination. This class implements theItemWriterinterface.Jobinterface: indicates a batch job.Stepinterface: indicates a step in a job.EnableBatchProcessingannotation: enables and configures Spring Batch features.JobBuilderFactoryclass: creates and configures jobs.StepBuilderFactoryclass: creates and configures steps.RunIdIncrementerclass: the run ID incrementer of Spring Batch, which is used to increment the run ID each time a job is run.ItemProcessorinterface: processes or converts the read items.ItemReaderinterface: reads items from the data source.ItemWriterinterface: writes processed or converted items to a specified destination.JdbcCursorItemReaderclass: reads data from the database and returns a cursor result set.Autowiredannotation: injects dependencies.Beanannotation: creates and configures beans.ComponentScanannotation: specifies the package or class to scan for components.Configurationannotation: marks a class as a configuration class.EnableAutoConfigurationannotation: enables automatic configuration of Spring Boot.SpringBootApplicationannotation: marks the class as the entry to the Spring Boot application.DataSourceinterface: obtains database connections.
The sample code is as follows:
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.In the class, define how data is read, processed, and written, and encapsulate these steps as a simple Spring Batch job. Use the annotations and automatic configuration feature of Spring Batch to create corresponding component instances by calling various
@Beanmethods, and use these components to read, process, and write data instep1.- Use
@Configurationto mark this class as a configuration class. - Use
@EnableBatchProcessingto enable Spring Batch. The annotation automatically creates necessary beans, such asJobRepositoryandJobLauncher. - Use
@SpringBootApplicationto mark the main class of the Spring Boot application. The Spring Boot application is launched from the main class. - Use
@ComponentScanto specify the package to scan for components. Spring Boot scans and registers all components in the package and its sub-packages. - Use
@EnableAutoConfigurationto automatically configure the infrastructure of the Spring Boot application.
The sample code is as follows:
@Configuration @EnableBatchProcessing @SpringBootApplication @ComponentScan("com.oceanbase.example.batch.writer") @EnableAutoConfiguration public class BatchConfig { }Use the
@Autowiredannotation.Use the
@Autowiredannotation to injectJobBuilderFactory,StepBuilderFactory, andDataSourceas member variables in theBatchConfigclass.JobBuilderFactoryis the factory class used to create and configure jobs.StepBuilderFactoryis the factory class used to create and configure steps.DataSourceis the interface used to obtain database connections.The sample code is as follows:
@Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Autowired private DataSource dataSource;Use the
@Beanannotation.Use the
@Beanannotation to define methods for creating readers, processors, writers, steps, and jobs.Call the
peopleReadermethod to create an instance of theItemReadercomponent. The component usesJdbcCursorItemReaderto readPeopleobjects from the database. Set the data source indataSource, setRowMapperto map database rows toPeopleobjects, and set the SQL query statement toSELECT * FROM people.Call the
addPeopleDescProcessormethod to create an instance of theItemProcessorcomponent. The component usesAddPeopleDescProcessorto processPeopleobjects and returnPeopleDESCobjects.Call the
addDescPeopleWritermethod to create an instance of theItemWritercomponent. The component uses theAddDescPeopleWriterto writePeopleDESCobjects to the destination.Call the
step1method to create an instance of theStepcomponent. Name the instance asstep1. CallstepBuilderFactory.getto get the step builder. Set the reader to theItemReadercomponent, the processor to theItemProcessorcomponent, the writer to theItemWritercomponent, and thechunksize to10. Callbuildto build and return the configuredStepinstance.Call the
importJobmethod to create an instance of theJobcomponent. Name the job asimportJob. CalljobBuilderFactory.getto get the job builder. Set the incrementer toRunIdIncrementerand the initial step inflowtoStep. Callbuildto build and return the configuredJobinstance.The sample code is as follows:
@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
Code in People.java
The People.java file defines a data model class named People to represent personnel information. The class contains two private member variables: name and age, and corresponding getter and setter methods. The toString method is overridden to print the object information. name indicates the name of a person, and age indicates the age of a person. The getter and setter methods get and set the values of these attributes.
The class provides data storage and transfer means for the input and output of a batch program. In batch reads and writes, People objects store data, setter methods set data, and getter methods get data.
The sample code is as follows:
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
}
Code in PeopleDESC.java
The PeopleDESC.java file defines a data model class named PeopleDESC to represent the description of personnel information. The PeopleDESC class contains four attributes: name, age, desc, and id, which represent the name, age, description, and identifier of a person. The class also contains corresponding getter and setter methods for getting 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 provides data storage and transfer means for the input and output of a batch program.
The sample code is as follows:
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 + "]";
}
}
Code in AddPeopleDescProcessor.java
The AddPeopleDescProcessor.java file defines a class named AddPeopleDescProcessor that implements the ItemProcessor interface for converting People objects to PeopleDESC objects.
To configure the AddPeopleDescProcessor.java file, perform the following steps:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
Peopleclass: stores personnel information read from the database.PeopleDESCclass: stores the description converted or processed from personnel information.ItemProcessorinterface: processes or converts the read items.
The sample code is as follows:
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 of theItemProcessorinterface convertsPeopleobjects toPeopleDESCobjects, thus implementing the processing logic for the input data during batch processing.In the
processmethod of this class, create aPeopleDESCobject nameddesc, and then use theitemparameter to obtain the attributes (nameandage) of thePeopleobject and set these attributes to thedescobject. At the same time, assign a value to thedescattribute of thedescobject. The value assignment logic is to generate the description of thePeopleobject based on its attributes. Finally, return the processedPeopleDESCobject.The sample code is as follows:
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; } }
Code in AddDescPeopleWriter.java
The AddDescPeopleWriter.java file implements the AddDescPeopleWriter class of the ItemWriter interface to write PeopleDESC objects to the database.
To configure the AddDescPeopleWriter.java file, perform the following steps:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
PeopleDESCclass: stores the description converted or processed from personnel information.ItemWriterinterface: writes processed or converted items to a specified destination.Autowiredannotation: injects dependencies.JdbcTemplateclass: provides methods for executing SQL statements.Listinterface: handles query result sets.
The sample code is as follows:
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 theJdbcTemplateinstance, which will be used to perform database operations for data writes.The sample code is as follows:
@Autowired private JdbcTemplate jdbcTemplate;In the
writemethod, traverseList<? extends PeopleDESC>that is passed in to fetch allPeopleDESCobjects in sequence.- Execute the SQL statement
DROP TABLE people_descto drop the table namedpeople_descthat may already exist. - Execute the SQL statement
CREATE 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. - Execute the SQL statement
INSERT INTO people_desc (id, name, age, description) VALUES (?, ?, ?, ?)to insert attribute values of eachPeopleDESCobject into thepeople_desctable.
The sample code is as follows:
@Override public void write(List<? extends PeopleDESC> items) throws Exception { // Drop the table that may already exist. String dropTableSql = "BEGIN EXECUTE IMMEDIATE 'DROP TABLE people_desc'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;"; jdbcTemplate.execute(dropTableSql); // 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()); } }- Execute the SQL statement
Code in AddPeopleWriter.java
The AddPeopleWriter.java file implements the AddPeopleWriter class of the ItemWriter interface to write People objects to the database.
To configure the AddPeopleWriter.java file, perform the following steps:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
Peopleclass: stores personnel information read from the database.ItemWriterinterface: writes processed or converted items to a specified destination.Autowiredannotation: injects dependencies.JdbcTemplateclass: provides methods for executing SQL statements.Componentannotation: marks the class as a Spring component.Listinterface: handles query result sets.
The sample code is as follows:
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 theJdbcTemplateinstance, which will be used to perform database operations for data writes.The sample code is as follows:
@Autowired private JdbcTemplate jdbcTemplate;In the
writemethod, traverseList<? extends People>that is passed in to fetch each allPeopleobjects in sequence.- Execute the SQL statement
DROP TABLE peopleto drop thepeopletable that may already exist. - Execute the SQL statement
CREATE TABLE people (name VARCHAR2(255), age INT)to create a table namedpeoplewith two columns:nameandage. - Execute the SQL statement
INSERT INTO people (name, age) VALUES (?, ?)to insert the attribute values of eachPeopleobject into thepeopletable.
The sample code is as follows:
@Override public void write(List<? extends People> items) throws Exception { // Drop the table that may already exist. String dropTableSql = "BEGIN EXECUTE IMMEDIATE 'DROP TABLE people'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;"; jdbcTemplate.execute(dropTableSql); // 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()); } }- Execute the SQL statement
Code in BatchConfigTest.java
The BatchConfigTest.java file defines a class for testing the job configuration of Spring Batch by using JUnit.
To configure the BatchConfigTest.java file, perform the following steps:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
Assertclass: asserts test results.Testannotation: marks a test method.RunWithannotation: specifies the test runner.Jobinterface: indicates a batch job.JobExecutionclass: indicates the execution of a batch job.JobParametersclass: indicates the parameters of a batch job.JobParametersBuilderclass: builds parameters of a batch job.JobLauncherinterface: launches a batch job.Autowiredannotation: injects dependencies.SpringBootTestannotation: marks the test class as a Spring Boot test.SpringRunnerclass: specifies SpringRunner as the test runner.
The sample code is as follows:
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;Define the
BatchConfigTestclass.With the
SpringBootTestannotation and theSpringRunnerrunner, this class can perform Spring Boot integration tests. In thetestJobmethod, use theJobLauncherTestUtilshelper class to launch a batch job and use an assertion to verify the execution status of the job.Use the
@Autowiredannotation to automatically inject theJobLauncherTestUtilsinstance.The sample code is as follows:
@Autowired private JobLauncherTestUtils jobLauncherTestUtils;Use the
@Testannotation to mark thetestJobmethod as a test method. In this method, create aJobParametersobject, call thejobLauncherTestUtils.launchJobmethod to launch the batch job, and then call theAssert.assertEqualsmethod to assert the execution status of the job asCOMPLETED.The sample code is as follows:
@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.The sample code is as follows:
@Autowired private JobLauncher jobLauncher;Use the
@Autowiredannotation to automatically inject theJobinstance.The sample code is as follows:
@Autowired private Job job;Define a private class named
JobLauncherTestUtilsto assist in launching a batch job. In the class, define thelaunchJobmethod for launching a batch job. In this method, call thejobLauncher.runmethod to launch a job and return the execution result of the job.The sample code is as follows:
private class JobLauncherTestUtils { public JobExecution launchJob(JobParameters jobParameters) throws Exception { return jobLauncher.run(job, jobParameters); } }
Code in AddPeopleDescProcessorTest.java
The AddPeopleDescProcessorTest.java file defines a class for testing the job configuration of Spring Batch by using JUnit.
To configure the AddPeopleDescProcessorTest.java file, perform the following steps:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
Peopleclass: stores personnel information read from the database.PeopleDESCclass: stores the description converted or processed from personnel information.Testannotation: marks a test method.RunWithannotation: specifies the test runner.Autowiredannotation: injects dependencies.SpringBootTestannotation: marks the test class as a Spring Boot test.SpringRunnerclass: specifies SpringRunner as the test runner.
The sample code is as follows:
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;Define the
AddPeopleDescProcessorTestclass.Use the
SpringBootTestannotation and theSpringRunnerrunner for Spring Boot integration testing.Use the
@Autowiredannotation to automatically inject theAddPeopleDescProcessorinstance.The sample code is as follows:
@Autowired private AddPeopleDescProcessor processor;Use the
@Testannotation to mark thetestProcessmethod as a test method. In this method, create aPeopleobject, call theprocessor.processmethod to process the object, and then assign the result to aPeopleDESCobject.The sample code is as follows:
@Test public void testProcess() throws Exception { People people = new People(); PeopleDESC desc = processor.process(people); }
Code in AddDescPeopleWriterTest.java
The AddDescPeopleWriterTest.java file defines a class for testing the write logic of AddDescPeopleWriter by using JUnit.
To configure the AddDescPeopleWriterTest.java file, perform the following steps:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
PeopleDESCclass: stores the description converted or processed from personnel information.Assertclass: asserts test results.Testannotation: marks a test method.RunWithannotation: specifies the test runner.Autowiredannotation: injects dependencies.SpringBootTestannotation: marks the test class as a Spring Boot test.JdbcTemplateclass: provides methods for executing SQL statements.SpringRunnerclass: specifies SpringRunner as the test runner.ArrayListclass: creates an empty list.Listinterface: handles query result sets.
The sample code is as follows:
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 for Spring Boot integration testing.Use
@Autowiredto inject instances. Use the@Autowiredannotation to automatically injectAddPeopleDescProcessorandJdbcTemplateinstances.The sample code is as follows:
@Autowired private AddDescPeopleWriter writer; @Autowired private JdbcTemplate jdbcTemplate;Use the method marked with
@Testto test data insertion and output. Use the@Testannotation to mark thetestWritemethod as a test method. In this method, create an emptypeopleDescListlist and then add twoPeopleDESCobjects to the list. Call thewriter.writemethod to write data in the list to the database. UsejdbcTemplateto execute the query statement that obtains data from thepeople_desctable. Execute the assertion statement to verify the correctness of the data. Output the query results to the console and output a message to indicate that job execution is complete.Insert data into the
people_desctable. Create an emptyPeopleDESCobject list namedpeopleDescList. Create twoPeopleDESCobjects nameddesc1anddesc2and set their attribute values. Adddesc1anddesc2to thepeopleDescListlist. Call thewritemethod ofwriterto write the objects in thepeopleDescListlist to thepeople_desctable in the database. CallJdbcTemplateto execute the query statementSELECT COUNT(*) FROM people_descthat obtains the number of records in thepeople_desctable. Assign the result to thecountvariable. Call theAssert.assertEqualsmethod to assert whether the value ofcountis2.The sample code is as follows:
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 the query statementSELECT * FROM people_desc, and use thelambdaexpression to process the query results. In thelambdaexpression, use methods such asrs.getIntandrs.getStringto obtain field values in the query result set and set the field values to the newly createdPeopleDESCobjects. Add all the newly createdPeopleDESCobjects to the result listresultDesc. Print the prompt lineData in the people_desc table:. Then, use aforloop to traverse theresultDesclist and useSystem.out.printlnto print thePeopleDESCobjects in the list one by one. Finally, print a message to indicate that job execution is complete.The sample code is as follows:
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 a message to indicate that job execution is complete. System.out.println("Batch Job execution completed.");
Code in AddPeopleWriterTest.java
The AddPeopleWriterTest.java file defines a class for testing the write logic of AddPeopleWriterTest by using JUnit.
To configure the AddPeopleWriterTest.java file, perform the following steps:
Reference other classes and interfaces.
Declare that the current file contains the following interfaces and classes:
Peopleclass: stores personnel information read from the database.Testannotation: marks a test method.RunWithannotation: specifies the test runner.Autowiredannotation: injects dependencies.SpringBootApplicationannotation: marks the class as the entry to the Spring Boot application.SpringBootTestannotation: marks the test class as a Spring Boot test.ComponentScanannotation: specifies the package or class to scan for components.JdbcTemplateclass: provides methods for executing SQL statements.SpringRunnerclass: specifiesSpringRunneras the test runner.ArrayListclass: creates an empty list.Listinterface: handles query result sets.
The sample code is as follows:
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 and theSpringRunnerrunner for Spring Boot integration testing, and use the@ComponentScanannotation to specify the package to scan.Use
@Autowiredto inject instances. Use the@Autowiredannotation to automatically injectaddPeopleWriterandJdbcTemplateinstances.The sample code is as follows:
@Autowired private AddPeopleWriter addPeopleWriter; @Autowired private JdbcTemplate jdbcTemplate;Use the method marked with
@Testto test data insertion and output.Insert data into the
peopletable. First, create an emptyPeopleobject list namedpeopleList. Then, create twoPeopleobjects:person1andperson2, and set their name and age attributes. Add the twoPeopleobjects to thepeopleListlist. Call thewritemethod ofaddPeopleWriterand passpeopleListto the method as an argument, so as to write thePeopleobjects to the database.The sample code is as follows:
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 data in the
peopletable. First, callJdbcTemplateto execute the query statementSELECT * FROM people, and use thelambdaexpression to process the query results. In thelambdaexpression, call thers.getStringandrs.getIntmethods to obtain the field values in the query result set and set the field values to newly createdPeopleobjects. Add all the newly createdPeopleobjects to the result listresult. Print the prompt lineData in the people table:. Then, use aforloop to traverse theresultlist and useSystem.out.printlnto print thePeopleobjects in the list one by one. Finally, print a message to indicate that job execution is complete.The sample code is as follows:
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 a message to indicate that job execution is complete. System.out.println("Batch Job execution completed.");
Complete code examples
<?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.oceanbase.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 automatic Spring Boot 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;
@Component
public class AddDescPeopleWriter implements ItemWriter<PeopleDESC> {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void write(List<? extends PeopleDESC> items) throws Exception {
// Drop the table that may already exist.
String dropTableSql = "BEGIN EXECUTE IMMEDIATE 'DROP TABLE people_desc'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;";
jdbcTemplate.execute(dropTableSql);
// 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 that may already exist.
String dropTableSql = "BEGIN EXECUTE IMMEDIATE 'DROP TABLE people'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;";
jdbcTemplate.execute(dropTableSql);
// 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 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;
@RunWith(SpringRunner.class)
@SpringBootTest
public class BatchConfigTest {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@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());
}
@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 a message to indicate that job execution is complete.
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 a message to indicate that job execution is complete.
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