当前位置: 首页 > news >正文

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.

相关文章:

  • 面试经典150题·LeetCode26·删除有序数组中的重复项·Java
  • 18.redis基本操作
  • 内积相似系数——内积度量相似系数
  • html 列表循环滚动,动态初始化字段数据
  • Android 隐藏手势模式下输入法的BackButton和ImeSwitchButton
  • Vue项目中Vuex在util引入,断点存在default
  • EI复现:蜣螂优化算法变体合集上新,改进正弦算法引导的蜣螂优化算法
  • ts中 构造器
  • 23种设计模式-结构型模式-桥接器
  • 【CF】Day20——Codeforces Round 969 (Div. 2) C
  • STM32 CAN学习(一)
  • linux-- 0. C语言过、Java半静对、Python纯动和C++对+C
  • mapState 函数的用法
  • 7.5 分治:归并:LeetCode 剑指 Offer 51.数组中的逆序对
  • docker 搭建部署知识库XWIKI
  • 【嵌入式学习3】信息安全 - SSH协议
  • JAVA反序列化深入学习(六):CommonsCollections4
  • jQuery 入门到精通
  • Vue中使用antd-table组件时,树形表格展开配置不生效-defaultExpandedRowKeys-默认展开配置不生效
  • 经典算法 排列的字典序问题
  • 商丘市住房和城乡建设厅网站/seo外链增加
  • 怎么登录手机wordpress/南昌seo优化
  • 如何推广自己网站链接/萧山seo
  • 网站框架设计图/上海网上推广
  • 介绍自己的做的网站/百度官网app
  • 温州建设公司网站/国外免费网站域名服务器查询