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 扩展性

创建项目

image-20201107134817228

选择数据库和spring batch

image-20201107134850794

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

image-20201107134924932

创建配置

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

image-20201107135012111

接着配置数据库

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配置类

image-20201107135116623

创建ItemReader

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

image-20201107135241687

创建ItemProcess

image-20201107135304534

创建ItemWriter

image-20201107135327646

组装Step

image-20201107135409954

配置Job

image-20201107135431435

配置数据库

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

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

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

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

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

image-20201107135713704

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

覆盖接口jobRepository

image-20201107135843277

注意

这里面有一个很大坑。

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

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

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

image-20201107140209999

就像这样,什么都没有。

提示Running default command line with: []

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

数据库驱动问题吗

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

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

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

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

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

发现还是不行。

开启debug级别

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

image-20201107140704297

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

image-20201107140755667

从日志中可以看出来,我们的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是一个批处理的框架,需要配合其他调度框架使用。

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

image-20201107143319098

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

image-20201107143509622

接着启动

image-20201107143541490

成功

另一个坑

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

image-20201107143639613

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

image-20201107143714944

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

所以,配置的是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中传入时间,即使我们不会用到。

这样保证可以重复执行。

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

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Batch中,可以使用Spring Retry框架来实现在数据库连接失败时进行重试。具体步骤如下: 1. 在pom.xml文件中添加Spring Retry的依赖: ``` <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.3.1</version> </dependency> ``` 2. 创建一个RetryTemplate对象,设置重试策略(例如,设置最大重试次数、重试的异常类型等): ``` @Bean public RetryTemplate retryTemplate() { RetryTemplate retryTemplate = new RetryTemplate(); SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(); retryPolicy.setMaxAttempts(3); Map<Class<? extends Throwable>, Boolean> exceptionsMap = new HashMap<>(); exceptionsMap.put(SQLException.class, true); ExceptionClassifierRetryPolicy exceptionClassifierRetryPolicy = new ExceptionClassifierRetryPolicy(); exceptionClassifierRetryPolicy.setPolicyMap(exceptionsMap); retryTemplate.setRetryPolicy(exceptionClassifierRetryPolicy); return retryTemplate; } ``` 3. 在Step中使用RetryTemplate执行任务(例如,执行查询语句): ``` @Bean public Step step1() { return stepBuilderFactory.get("step1") .<Person, Person>chunk(10) .reader(itemReader()) .processor(itemProcessor()) .writer(itemWriter()) .faultTolerant() .retryTemplate(retryTemplate()) .retryLimit(3) .build(); } ``` 在上面的代码中,我们通过调用faultTolerant()方法来启用重试机制,并设置了RetryTemplate和最大重试次数。当查询语句执行失败时,Spring Batch会自动使用RetryTemplate进行重试,直到达到最大重试次数或任务成功执行为止。 注意:为了确保数据库连接失败时可以进行重试,需要在数据库连接URL中添加retry参数,例如: ``` jdbc:mysql://localhost/mydb?autoReconnect=true&useSSL=false&retry=true ``` 这样,当数据库连接失败时,驱动程序会自动尝试重新连接数据库,并通过Spring Retry进行重试。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值