Skip to content

Spring Batch + MySQL

🏷️ Spring Batch

Spring Batch 需要存储数据以记录 Job 运行的参数、步骤等信息,这里以 MySQL 为例(需要添加 mysql-connector-j 依赖)。

完整的 pom.xml 文件如下:

xml
<?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 http://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.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>me.liujiajia.batch</groupId>
    <artifactId>chapter04</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

需要在 application.yml 文件中添加 MySQL 配置:

yaml
spring:
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/spring_batch
    username: root
    password: myPwd3

安装了 docker 的话,可以运行如下命令在本地启动一个 mysql 服务器:

bash
docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=myPwd3 -d -p 3306:3306 mysql:8.0.31

创建一个名为 spring_batch 的数据库。

sql
CREATE DATABASE `spring_batch`;

运行时由于数据库还没有创建对应的表结构,会报如下错误:

java.sql.SQLSyntaxErrorException: Table 'spring_batch.BATCH_JOB_INSTANCE' doesn't exist

application.yml 中添加如下配置可以在每次启动时判断是否需要初始化数据库:

yaml
spring:
  batch:
    jdbc:
      initialize-schema: always

注意:
书中使用的是 spring.batch.initialize-schema 配置项,在当前使用的版本中,这个配置已经过期了,配置了不起作用。需要修改为使用 spring.batch.jdbc.initialize-schema 配置。

再次启动会自动创建 Spring Batch 使用到的数据库表:

  • BATCH_JOB_EXECUTION
  • BATCH_JOB_EXECUTION_CONTEXT
  • BATCH_JOB_EXECUTION_PARAMS
  • BATCH_JOB_EXECUTION_SEQ
  • BATCH_JOB_INSTANCE
  • BATCH_JOB_SEQ
  • BATCH_STEP_EXECUTION
  • BATCH_STEP_EXECUTION_CONTEXT
  • BATCH_STEP_EXECUTION_SEQ

ER 图:

结构比较简单,可以很直观的看到表之间的关系。正好也对应了代码中 JobInstanceJobExecutionStepExecution 之间的关系。

一个 JobInstance 只能成功运行一次,也就是说如果运行失败了,就会有出现运行多次的情况,也就会产生多个 JobExecution 。由于 Job 可能会有多个 Step,所以每个 JobExecution 有可能会对应多个 StepExecution

_CONTEXT 后缀的是对应的上下文表,_PARAMS 后缀的是参数表,_SEQ 后缀的是用来分配对应主键的表。

参考

[1]:《Spring Batch 权威指南》 -- [美] 迈克尔·T.米内拉(Michael,T.,Minella)著