Springboot之Spring Batch批处理功能实现

Springboot之Spring Batch整合

文章目录

  • Springboot之Spring Batch整合
  • 前言
  • 一、SpringBatch 核心组件简介
  • 二、SpringBatch是批处理框架
  • 三、SpringBatch工作原理
  • 四、SpringBatch优势
  • 五、Spring Batch提供的读-处理-写组件简介
  • 六、Spring Batch开发实战
    • 1、创建项目,添加pom依赖
    • 2、添加application配置
    • 3、开启springBatch功能
    • 4、配置config
    • 5、映射实体
    • 6、测试demo.csv放在资源目录下
    • 7、添加测试单元模块
    • 8、启动服务,生成批处理的表
    • 9、test单元模块测试
    • 10、注意点

前言

Spring Bath是一个开源的、全面的、轻量级的批处理框架,通过Spring Batch可以实现批处理应用程序的开发;除此之外,还提供记录/跟踪、事物管理、作业处理统计、作业重启、以及资源管理等功能。Spring Batch结合定时任务可以发挥更大的作用。
下面先看简介原理,再来实战

一、SpringBatch 核心组件简介

SpringBatch 核心组件简介:
1)JobRepository:用来注册Job容器,设置数据库相关属性。
2)JobLauncher:用来启动Job的接口
3)Job:我们要实际执行的任务,包含一个或多个
4)Step:即步骤,包括:ItemReader->ItemProcessor->ItemWriter
5)ItemReader:用来读取数据,做实体类与数据字段之间的映射。比如读取csv文件中的人员数据,之后对应实体AuthUser的字段做mapper
6)ItemProcessor:用来处理数据的接口,同时可以做数据校验(设置校验器,使用JSR-303(hibernate-validator)注解)
7)ItemWriter:用来输出数据的接口,设置数据库源。编写预处理SQL插入语句

二、SpringBatch是批处理框架

从早期的spring开发,到Spring MVC的web开发,再到现在的基于Spring Boot进行微服务开发,都具有简化开发,增强规范,快速集成等特点,而在数据处理领域,spring同样有一个开发框架,那就是Spring Batch。Spring Batch是一个轻量级,完善的批处理框架,旨在帮助企业建立健壮高效的批处理应用程序。 它是以Spring 框架为基础开发,使得原来使用Spring框架的开发者可以更容易利用原来的服务。当前新版本的Spring Batch更是可以直接基于Spring Boot进行开发,使得开发更简单、快捷。

三、SpringBatch工作原理

Springboot之Spring Batch批处理功能实现_第1张图片

  • 一个Batch(批处理)过程由一个Job(作业)组成。这个实体封装了整个批处理过程。
  • 一个Job(作业)可以由一个或多个Step(步骤)组成。在大多数情况下,一个步骤将读取数据(通过ItemReader),处理数据(使用ItemProcessor),然后写入数据(通过ItemWriter)。
  • JobLauncher处理启动一个Job(作业)。
  • 最后,JobRepository存储关于配置和执行的Job(作业)的元数据。

四、SpringBatch优势

  • 丰富的开箱即用组件
    开箱即用组件包括各种资源的读、写。读/写:支持文本文件读/写、XML文件读/写、数据库读/写、JMS队列读/写等。还提供作业仓库,作业调度器等基础设施,大大简化开发复杂度。
  • 面向chunk处理
    支持多次读、一次写、避免多次对资源的写入,大幅提升批处理效率。
  • 事务管理能力
    默认采用Spring提供的声明式事务管理模型,面向Chunk的操作支持事务管理,同时支持为每个tasklet操作设置细粒度的事务配置:隔离级别、传播行为、超时设置等。
  • 元数据管理
    自动记录Job和Step的执行情况、包括成功、失败、失败的异常信息、执行次数、重试次数、跳过次数、执行时间等,方便后期的维护和查看。
  • 易监控的批处理应用
    提供了灵活的监控模式,包括直接查看数据库、通过Spring Batch提供的API查看、JMX控制台查看等。其中还说到Spring Batch Admin,不过这个项目已不维护,改为用Spring Cloud Data Flow了。
  • 丰富的流程定义
    支持顺序任务、条件分支任务、基于这两种任务可以组织复杂的任务流程。
  • 健壮的批处理应用
    支持作业的跳过、重试、重启能力、避免因错误导致批处理作业的异常中断。
  • 易扩展的批处理应用
    扩展机制包括多线程执行一个Step(Multithreaded step)、多线程并行执行多个Step(Parallelizing step)、远程执行作业(Remote chunking)、分区执行(partitioning step)。
  • 复用企业现有IT资产
    提供多种Adapter能力,使得企业现有的服务可以方便集成到批处理应用中。避免重新开发、达到复用企业遗留的服务资产。

五、Spring Batch提供的读-处理-写组件简介

  • ItemReader
ItemReader 说明
ListItemReader 读取List类型数据,只能读一次
ItemReaderAdapter ItemReader适配器,可以复用现有的读操作
FlatFileItemReader 读Flat类型文件
StaxEventItemReader 读XML类型文件
JdbcCursorItemReader 基于JDBC游标方式读数据库
HibernateCursorItemReader 基于Hibernate游标方式读数据库
StoredProcedureItemReader 基于存储过程读数据库
JpaPagingItemReader 基于Jpa方式分页读数据库
JdbcPagingItemReader 基于JDBC方式分页读数据库
HibernatePagingItemReader 基于Hibernate方式分页读取数据库
JmsItemReader 读取JMS队列
IteratorItemReader 迭代方式的读组件
MultiResourceItemReader 多文件读组件
MongoItemReader 基于分布式文件存储的数据库 MongoDB读组件
Neo4jItemReader 面向网络的数据库Neo4j的读组件
ResourcesItemReader 基于批量资源的读组件,每次读取返回资源对象 AmqpItemReader读取AMQP队列组件
RepositoryItemReader 基于 Spring Data的读组件
  • ItemProcessor
ItemProcessor 说明
CompositeItemProcessor 组合处理器,可以封装多个业务处理服务
ItemProcessorAdapter ItemProcessor适配器,可以复用现有的业务处理服务
PassThroughItemProcessor 不做任何业务处理,直接返回读到的数据
ValidatingItemProcessor 数据校验处理器,支持对数据的校验,如果校验不通过可以进行过滤掉或者通过skip的方式跳过对记录的处理
  • ItemWriter
ItemWriter 说明
FlatFileItemWriter 写Flat类型文件
MultiResourceItemWriter 多文件写组件
StaxEventItemWriter 写XML类型文件
AmqpItemWriter 写AMQP类型消息
ClassifierCompositeItemWriter 根据 Classifier路由不同的Item到特定的ItemWriter处理
HiberateItemWriter 基于Hibernate方式写数据库
ItemWriterAdapter ItemWriter适配器,可以复用现有的写服务
JdbcBatchItemWriter 基于JDBC方式写数据库
JmsItemWriter 写JMS队列 JpaItemWriter基于Jpa方式写数据库
GemfireItemWriter 基于分布式数据库Gemfire的写组件
SpELMappingGemfireItemWriter 基于Spring表达式语言写分布式数据库Gemfire的写组件
MimeMessageItemWriter 发送邮件的写组件
MongoItemWriter 基于分布式文件存储的数据库MongoDB写组件
Neo4jItemWriter 面向网络的数据库Neo4j的读组件
PropertyExtractingDelegatingItemWriter 属性抽取代理写组件:通过调用给定的 Spring Bean方法执行写入,参数由Item中指定的属性字段获取作为参数
RepositoryItemWriter基于 Spring Data的写组件
SimpleMailMessageItemWriter 发送邮件的写组件
CompositeItemWriter 条目写的组合模式,支持组装多个ItemWriter

六、Spring Batch开发实战

整体流程:从csv文件中读数据,写入到mysql数据库,只需要使用FlatFileItemReader和JdbcBatchItemWriter即可。

1、创建项目,添加pom依赖

<?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.3.5.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.yangxf</groupId>
	<artifactId>demoBatch</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demoBatch</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
	</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-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.10</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</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>

2、添加application配置

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/batch_demo?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT
spring.datasource.username=root
spring.datasource.password=1234%^&*
spring.datasource.schema=classpath:/org/springframework/batch/core/schema-mysql.sql
##禁止自动执行
spring.batch.initialize-schema=always
spring.batch.job.enabled=false

3、开启springBatch功能

package com.yangxf.demoBatch;

import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableBatchProcessing//开启springbatch框架功能
public class DemoBatchApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoBatchApplication.class, args);
	}

}

4、配置config

/**
 * FileName: ExcelBatchConfig
 * Author:   linwd
 * Date:     2021/5/5 14:07
 * Description: 批量导入数据
 * History:
 *           
package com.yangxf.demoBatch.config;

import com.yangxf.demoBatch.entity.User;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import javax.sql.DataSource;

/**
 * 〈一句话功能简述〉
* 〈批量导入数据〉 * * @author linwd * @create 2021/5/5 * @since 1.0.0 */
@Configuration public class ExcelBatchConfig { @Autowired JobBuilderFactory jobBuilderFactory; @Autowired StepBuilderFactory stepBuilderFactory; @Autowired DataSource dataSource; @Bean @StepScope FlatFileItemReader <User> itemReader(){ FlatFileItemReader<User> reader=new FlatFileItemReader<>(); reader.setLinesToSkip(1); reader.setEncoding("UTF-8");//设置文件编码格式,csv默认编码格式为ANSI,demoexcel保存后,需要用文本文档打开,然后另存为时,将默认的编码格式调整为UTF-8,否则保存到数据库中的中文乱码 reader.setResource(new ClassPathResource("demo.csv")); reader.setLineMapper(new DefaultLineMapper<User>(){{ setLineTokenizer(new DelimitedLineTokenizer(){{ setNames("id","username","sex","addr"); setDelimiter(","); }}); setFieldSetMapper(new BeanWrapperFieldSetMapper<User>(){{ setTargetType(User.class); }}); }}); return reader; } @Bean JdbcBatchItemWriter jdbcBatchItemWriter(){ JdbcBatchItemWriter writer=new JdbcBatchItemWriter(); writer.setDataSource(dataSource); writer.setSql("insert into t_user (id,username,sex,addr) values (:id,:username,:sex,:addr)"); writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>()); return writer; } @Bean Step excleStep(){ return stepBuilderFactory.get("excleStep") .<User,User>chunk(5000) .reader(itemReader()) .writer(jdbcBatchItemWriter()) .build(); } @Bean Job excelJob(){ return jobBuilderFactory.get("excelJob") .start(excleStep()) .build(); } }

5、映射实体

/**
 * FileName: Entity
 * Author:   linwd
 * Date:     2021/5/5 14:10
 * Description:
 * History:
 *           
package com.yangxf.demoBatch.entity;

/**
 * 〈一句话功能简述〉
* 〈〉 * * @author linwd * @create 2021/5/5 * @since 1.0.0 */
public class User { private Integer id; private String username; private String sex; private String addr; public User() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } }

6、测试demo.csv放在资源目录下

Springboot之Spring Batch批处理功能实现_第2张图片

7、添加测试单元模块

package com.yangxf.demoBatch;

import org.junit.jupiter.api.Test;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoBatchApplicationTests {
	@Autowired
	JobLauncher jobLauncher;
	@Autowired
	Job job;
	@Test
	void bathcTest() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
		jobLauncher.run(job,new JobParametersBuilder().toJobParameters());
	}

}

8、启动服务,生成批处理的表

Springboot之Spring Batch批处理功能实现_第3张图片

9、test单元模块测试

生成业务表数据。

10、注意点

1、不支持excel格式,默认支持csv格式。
2、csv文件默认编码格式为ANSI,需要调整为UTF-8。
3 、执行sql注意不要写错。

你可能感兴趣的:(springboot,java后台,spring,boot,spring,batch,批处理)