一:简介
SpringBatch 是一个轻量级的批处理框架,适合处理大批量的数据(如百万级别)。功能就是从一个地方读数据写到另一个地方去。一般都是系统之间不能直接访问同一个数据库,需要通过文件来交换数据。
二:从文件中读然后写到数据库这代码谁都会写,那么为什么还要使用框架?
try(BufferedReader bufferedReader = new BufferedReader(new FileReader("/static/user.csv"));) {
String line = null;
while ((line = bufferedReader.readLine()) != null) {
final String[] values = line.split(",");
userService.insertUser(new User(Long.parseLong(values[0]), values[1], Integer.parseInt(values[2]), values[3]));
}
}
自己写需要体力而且功能比较简单,容错性不强, Spring Batch 框架提供丰富的开箱即用
的组件和高可靠性
、高扩展性
的能力,使得开发批处理应用的人员专注于业务处理。既然不用自己写又能获得超能力,那为何不用?
- 支持多种数据源(平面文件、数据库、JSON、XML等)
支持分块和分区处理
。支持多线程处理
。- 支持文件行数据自动转成实体类。
- 支持重启。
- 支持重试retry(在上一次发生错误的步骤继续执行)。
- 支持跳过skip(对异常数据不处理)。
有一套表可以记录作业执行的具体信息
。
三:环境搭建 SpringMVC + SpringBatch + MyBatis
3.1 pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.14</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
3.2 application.yml
spring.batch.job.enabled
: 启动项目时是否立即执行作业。- true:程序启动时立即执行Job。
false
:程序启动时不执行,通过controller来触发接口执行。一般配置false
。
spring.batch.initialize-schema
:启动项目时是否生成spring batch表结构。- always:启动时总是检查表结构是否存在,不存在就创建,存在则不处理。
never
:表示一直都不生成。一般第一次启动项目使用always生成表结构,后面都使用never。
- spring.batch.schema: 生成表结构的sql文件位置。
spring:
datasource:
url: jdbc:mysql://localhost:3306/springbatch?useUnicode=true&characterEncoding=utf8
username: root
password: root123
driver-class-name: com.mysql.cj.jdbc.Driver
druid:
#初始化连接池的连接数量 大小,最小,最大
initial-size: 10
min-idle: 10
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: false
max-pool-prepared-statement-per-connection-size: 20
batch:
initialize-schema: always # never
schema: classpath:org/springframework/batch/core/schema-mysql.sql
job:
enabled: false # 任务是否自动执行,true项目启动时就会执行,false通过启动器执行
## Mybatis 配置
mybatis:
typeAliasesPackage: com.example.mybatis.entity
mapperLocations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
cache-enabled: true
default-executor-type: batch
# 打印mapper日志
logging:
level:
com.example.batch.mapper: debug
3.3 main
@EnableBatchProcessing
:开启SpringBatch,配置在启动类
或者配置类
上。
@EnableBatchProcessing
@SpringBootApplication
@MapperScan("com.example.batch.mapper")
public class SpringbootSpringbatchApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootSpringbatchApplication.class, args);
}
}
@Configuration
@EnableBatchProcessing
public class HelloWorldJobConfig {
}
3.4 entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String username;
private Integer age;
private String address;
}
3.5 mapper
public interface UserMapper {
void insertUser(User user);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.batch.mapper.UserMapper">
<insert id="insertUser">
insert into tbl_user(id, username, age, address)values(#{id}, #{username}, #{age}, #{address})
</insert>
</mapper>
CREATE TABLE `tbl_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
3.6 service
public interface UserService {
void insertUser(User user);
}
@Slf4j
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Transactional
@Override
public void insertUser(User user) {
userMapper.insertUser(user);
}
}
3.7 controller
http://localhost:8080/user/insert
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/insert")
public String insertUser(User user) throws Exception {
userService.insertUser(user);
return "ok";
}
}
3.8 启动SpringBoot工程生成表结构
总共有9张表。BATCH_JOB_EXECUTION_SEQ和BATCH_JOB_SEQ 初始化一条数据(ID=0, UNIQUE_KEY=0)
四:慢读
请允许一切发生
你要允许你爱的人不爱你,
你要允许你的工作为难你,
你要允许你身后有人算计你,
你要是不允许你,那你就是在跟自己较劲,
较完劲之后,那种无能为力和力不从心才是常态,
很多人很多事,冥冥之中自有安排,
允许自己做自己,允许别人做别人。