spring batch连接数据库


github地址:

​https://github.com/a18792721831/studybatch.git​

文章列表:

​spring batch 入门​

​spring batch连接数据库​

​spring batch元数据​

​spring batch Job详解​

​spring batch step详解​

​spring batch ItemReader详解​

​spring batch itemProcess详解​

​spring batch itemWriter详解​

​spring batch 作业流​

​spring batch 健壮性​

​spring batch 扩展性​

创建项目

spring batch连接数据库_batch跳过job

选择数据库和spring batch

spring batch连接数据库_batch连接数据库_02

下载完依赖后,目录结构如下

spring batch连接数据库_batch连接数据库_03

创建配置

在resources目录下创建application.yaml配置文件

spring batch连接数据库_batch连接数据库_04

接着配置数据库

spring:
main:
allow-bean-definition-overriding: true
datasource:
username: springbatch
password: springbatch
url: jdbc:oracle:thin:@10.0.250.178:1521/starboss
driver-class-name: oracle.jdbc.OracleDriver
initialization-mode: embedded
schema: classpath:/org/springframework/batch/core/schema-oracle10g.sql
batch:
initialize-schema: embedded
job:
enabled: true
names: study2-oracle

创建job

创建job配置类

spring batch连接数据库_batch无法执行job_05

创建ItemReader

我们不使用spring batch提供的已经实现的包装好的数据读取器,而是直接实现接口。

spring batch连接数据库_batch连接数据库_06

创建ItemProcess

spring batch连接数据库_batch无法执行job_07

创建ItemWriter

spring batch连接数据库_batch无法执行job_08

组装Step

spring batch连接数据库_batch跳过job_09

配置Job

spring batch连接数据库_batch连接数据库_10

配置数据库

到目前为止,我们已经创建了一个标准的job。创建job的过程中,需要使用到jobBuilderFactory和stepBuilderFactory.

我们使用的jobBuilderFactory和stepBuilderFactory是spring batch注入的。

spring batch注入的这两个接口,使用的是默认的配置。

而我们在application.yaml中配置的oracle数据库,却没有被用到。

所以,还需要配置数据库。

spring batch连接数据库_batch跳过job_11

我们在容器中注入了相关的配置,没有注入使用我们想要的配置的接口。

覆盖接口jobRepository

spring batch连接数据库_batch连接数据库_12

注意

这里面有一个很大坑。

在spring batch的quick start中 ,并没有需要我们自己去执行job,而是只需要将job注入容器,然后就会执行。

理所当然的,我们配置了oracle数据库后,也会认为,我们只需要将job注入容器,然后将使用了数据库配置的jobRepository注入容器,就可以了。

当然,我也是这么想的,所以,我将这一切配置好后,启动,发现了一个很有意思的事情:

spring batch连接数据库_batch连接数据库_13

就像这样,什么都没有。

提示​​Running default command line with: []​

什么鬼,我们不是已经将job注入容器了吗,为什么不执行?

数据库驱动问题吗

网上有很多的资料说,数据库的驱动,版本问题,很容易出现问题。

于是,我就创建了另外一个项目:mysql的。

相比来说,oracle数据库驱动,因为不容易下载等原因,问题总是比mysql多些。

可惜的是,换成了mysql数据库后,还是相同的。

我更换了网上常见的ojdbc8,12,14等等,各种版本。

发现还是不行。

开启debug级别

想着开启debug之后,打印的信息更多,可能会看出问题的原因来:

spring batch连接数据库_batch连接数据库_14

开启debug级别的日志后,确实打印的信息更多了

spring batch连接数据库_batch无法执行job_15

从日志中可以看出来,我们的job配置是没有任何问题的。

容器扫描到了job,但是却被spring batch跳过了。

原因是从注册元数据中没有找到这个job。

什么情况,我们使用jobBuilderFactory.get(“hello-job”)不就是想注册这个job么。

是不是数据库就没有连上?

于是,我创建了一个新的oracle数据库用户,接着配置了oracle用户,在其他数据不修改的情况下,启动。

发现还是这样。

而且,数据库中,根本就没有执行init-schema脚本。

数据库真的没有连上。(还是太年轻)

但是数据库连接就是这样配置啊,驱动,配置等等都有了。还需要怎么做呢?

重新阅读quick start

确实不甘心,我要学习spring batch,怎么在第一步上就放弃呢。

重新阅读quick start。没有发现什么有用的信息。

我强迫自己忘记现在已经做的全部事情,从头开始。

避免惯性思维。

于是从头开始,重新按照教程做了一遍。

发现和我的项目的区别就是数据库不同。

于是我将我之前的oracle数据库在换回hsql数据库。

神奇的一幕出现了:

在hsql中,我们将job注入容器就可以了,启动项目,spring batch中会默认调度我们的job。

在oracle中,我们将job注入容器,一点屁用都没有,甚至,初始化脚本都不会执行。

破局

我发现这个差异,就去github,stackoverflow中搜索spring batch oracle。发现没有什么有用的回答。

继续回想看到的资料,说pring batch是一个批处理的框架,需要配合其他调度框架使用。

我可能明白了,需要我们自己调度。

spring batch连接数据库_batch无法执行job_16

于是,我在job的配置类中,写了调度方法

spring batch连接数据库_batch跳过job_17

接着启动

spring batch连接数据库_batch连接数据库_18

成功

另一个坑

在spring batch的配置中,还有一个地方有坑。

spring batch连接数据库_batch无法执行job_19

在数据库初始化策略中,有三种模式:

spring batch连接数据库_batch连接数据库_20

从不初始化,每次都初始化,根据需要初始化。

所以,配置的是embedded.

结果,并不会初始化,oracle数据库。或许,是我自己理解有误,只有切入式的数据库,才使用embedded。

所以,第一次启动oracle数据库,我们需要将初始化策略配置为always,或者将初始化脚本手动执行。

然后将初始化策略配置为never。

这部分在github的issus中也得到了侧面验证。初始化脚本和数据库用户的权限问题。配置的数据库用户只有数据的读写权限,没有数据表操作权限。

也就是,dml和ddl是分离的。

如果使用oracle数据库,那么使用embedded和never是一样的效果。

另一种不执行的情况

job instance执行成功后,就不在重复执行。

刚开始,我启动job的时候,配置的jobParameter是空的。

第一次执行没有问题,第二次执行,就是跳过这个job instance了。

因为在spring batch中,识别一个job instance = job name + job parameter

我们两次执行的parameter是相同的,也就是同一个job instance,因为job instance已经执行成功了,就不在重复执行了。

所以,最好是job parameter中传入时间,即使我们不会用到。

这样保证可以重复执行。

这个问题,耗费了我好几天的学习时间才解决,希望可以帮到你。