Springboot3.x集成Spring Batch 5.2.1
Springboot3.x集成Spring Batch 5.2.1
Spring Batch是一个轻量级的、全面的批处理框架,旨在开发健壮的批处理应用程序,这些对企业系统的日常操作至关重要。
这里通过范例演示批量读取csv文件中的数据,写入mysql数据库。虽然简单,但涉及了Spring Batch 5.2.1框架的各个部分的使用。
依赖配置
<!-- Spring Batch 核心依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<!-- MySQL 驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
数据库配置(application.yml)
spring:
batch:
job:
enabled: true # 自动执行Job
sql:
init:
mode: never # always
schema-locations: classpath:schema-mysql.sql
datasource:
url: jdbc:mysql://localhost:3306/dbjava
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
logging:
level:
org.springframework.transaction: DEBUG
定义数据模型
/**
* @ 基本功能:
* @ program:demobatch
* @ author:Jet
* @ create:2025-03-06 17:32:26
**/
@Data
public class User {
private Long id;
private String name;
private int score;
}
配置批处理作业
/**
* @ 基本功能:
* @ program:demobatch
* @ author:Jet
* @ create:2025-03-06 17:05:38
**/
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
// ItemReader(读取CSV文件)
@Bean
public FlatFileItemReader<User> reader() {
return new FlatFileItemReaderBuilder<User>()
.name("userReader")
.resource(new ClassPathResource("users.csv"))
.delimited().names("id", "name", "score")
.targetType(User.class)
.build();
}
// ItemWriter(写入MySQL)
@Bean
public JdbcBatchItemWriter<User> writer(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<User>()
.sql("INSERT INTO users (id, name, score) VALUES (0, :name, :score)")
.dataSource(dataSource)
.beanMapped()
.build();
}
// ItemProcessor(数据过滤)
@Bean("addProcessor")
public ItemProcessor<User, User> userItemProcessor() {
return item -> {
item.setScore(item.getScore() + 1);
// 可选的数据处理逻辑
return item;
};
}
@Bean
public Job importUserJob(JobRepository jobRepository, Step step) {
return new JobBuilder("importUserJob", jobRepository)
.start(step)
.build();
}
@Bean
public Step step(JobRepository jobRepository, PlatformTransactionManager txManager,
ItemReader<User> reader, ItemWriter<User> writer, ScoreFilterProcessor itemProcessor) {
return new StepBuilder("processStep", jobRepository)
.<User, User>chunk(100, txManager)
.reader(reader)
.processor(itemProcessor)
.writer(writer)
.build();
}
}
添加控制器
/**
* @ 基本功能:
* @ program:demobatch
* @ author:Jet
* @ create:2025-03-06 18:02:30
**/
@RestController
public class JobController {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job importUserJob; // 注入定义的Job Bean
@GetMapping("/runJob")
public String runJob() throws Exception {
JobParameters jobParameters = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.toJobParameters();
jobLauncher.run(importUserJob, jobParameters);
return "Job triggered";
}
}
数据文件
在src/main/resources下创建users.csv:
1,Alice,85
2,Bob,55
3,Charlie,92
创建数据库表
执行SQL:
CREATE TABLE users (
id BIGINT PRIMARY KEY,
name VARCHAR(50),
score INT
);
注意事项
问题一:
新建springboot3.4.3的项目,添加spring-boot-starter-batch 3.4.3依赖后,无法启动,报错,删除该依赖就可以正常启动
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
原因:
检查spring-boot-starter-batch 3.4.3发现编译依赖spring-boot-starter-jdbc
Spring Batch 使用JobRepository来存储元数据,如JobExecution、StepExecution等。默认情况下,Spring Boot会自动配置一个基于JDBC的JobRepository。
解决办法:
需要添加数据库驱动,这里添加mysql驱动依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
application.yml中添加数据库配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/dbjava
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
问题二:
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME FROM BATCH_JOB_INSTANCE WHERE JOB_NAME = ? and JOB_KEY = ?]
原因:元数据表未初始化,Spring Batch依赖BATCH_JOB_INSTANCE等元数据表
检查Batch元数据表
方法:执行SHOW TABLES LIKE 'BATCH_JOB_INSTANCE';
解决办法:
若未自动创建,需手动执行初始化脚本
下载schema-mysql.sql脚本文件
下载地址:
https://github.com/spring-projects/spring-batch/tree/main/spring-batch-core/src/main/resources/org/springframework/batch/core
方式一自动执行sql脚本
配置如下:
spring:
sql:
init:
mode: always # never
schema-locations: classpath:schema-mysql.sql
把schema-mysql.sql脚本文件放在resources目录下
网上的很多教程都只告诉你,设置mode为always,没有告诉你通过schema-locations指定Spring Boot初始化数据库时应加载的schema脚本的位置。所以启动springboot项目时并不会自动创建元数据表,害人不浅。
mode:控制 SQL 初始化的模式,取值可以是:
• never:禁用初始化。
• embedded:仅在嵌入式数据库中初始化。
• always:每次应用启动时都初始化。
第一次运行时mode设置为always,初始化之后,就可以改为never.