Job Repository 数据库方式的配置

写在最前

1、为方便开发,本程序所用框架为springboot+mybatis,同时mybatis还集成了 generator 插件;如果对这些开发环境不熟悉,建议先查询相关资料,搭建springboot+mybatis环境,再集成spring batch。

2、在配置job、step等spring batch 的bean时,用的是java config方式,如想用xml方式配置,可参考 之前的博客:https://blog.csdn.net/Chris___/article/details/103166094

3、源代码github: https://github.com/Horven-Jane/springBatchDemo1,可用于快速验证。

 

 ------------------------------------------------------------------------------------------------------------------------------------------------

 

Job Repository 用来存储Job执行期的元数据,这里的元数据是指Job Instance、Job Execution、Job Parameters、StepExecution、Execution Context等数据。

有关元数据的介绍,这里暂不做详细介绍,读者暂时可以将它们理解为spring batch运行时产生的一些中间数据。

有两种Job Repository 的实现方式,一种是存放在内存中,这在之前的博客中介绍了(https://blog.csdn.net/Chris___/article/details/103166094);另一种则是将元数据存放在数据库中。

 

本篇文章介绍第二种方式——DB Job Repository。

将元数据存放在数据库的好处:可以随时监控批处理Job的执行状态,查看Job执行结果是成功还是失败,并且使得在job失败的情况下重启Job成为可能。

 

以下是详细步骤。

 

一、初始化数据库

初始化数据库,是指要建立相应的数据库表,以便存放元数据。spring batch已经提供了相应的建表、销表语句。

在包spring-batch-core jar包下的 org.springframework.batch.core 目录中,可以找到相应的sql文件,如下:

 

本示例所用的数据库是Mysql,因此执行 schema-mysql.sql 中的语句,即可完成初始化。

如果想销表,则执行 schema-drop-mysql.sql

 

初始化数据库后,可以看到有9张元数据表:

 

 

表对应的描述如下:

二、搭建springboot+mybatis 环境

 

本项目采用springboot+mybatsi作为框架,并用了mybatis的generator功能。

项目的业务场景是:从文件中读取出用户的信用卡消费账单,简单处理后(因为是示例,所以这里的处理只是打印出一句话),将这些账单写入数据库。

 

项目的整体结构如下:

关于springboot+mybatis的集成,这里不多介绍,可以查看博客:https://blog.csdn.net/iku5200/article/details/82856621

 

 

以下是详细步骤。

1、建立一个maven工程,引入springboot、mybatis 以及 spring batch的相关包,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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.maple</groupId>
    <artifactId>springBatchStudy02</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>2.1.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- spring boot 整合 spring batch 的jar包  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <!-- mybatis generator 自动生成代码插件 -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <configurationFile>${basedir}\src\main\resources\generatorConfig.xml</configurationFile>
                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

2、接着配置数据库连接,编写application.properties以及application-dev.properties文件。

application.properties 中只有一句话:

spring.profiles.active=dev

表示当前环境是dev。

 

application-dev.properties 内容如下:

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/spring_batch?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

mybatis.mapper-locations=classpath:mapping/*.xml
#全局的映射,不用在xml文件写实体类的全路径
mybatis.type-aliases-package=com.maple.model

#开启驼峰映射
mybatis.configuration.map-underscore-to-camel-case=true

所用的数据源是Druid。

 

3、编写业务代码

编写业务实体类CreditBill,该类有5个字段,如下:

public class CreditBill implements Serializable {

    private String accountId;

    private String name;

    private Double txnAmount;

    private String txnDate;

    private String address;
}

利用mybatis的 generator 生成相应的Mapper 文件,以方便操作数据库。

 

4、配置作业(Java Config 方式 )

用Java Config 来配置 Job 以及Step。这是本文的重点。文件BatchConfig02.java内容如下:

@Configuration
@EnableBatchProcessing
public class BatchConfig02 {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public FlatFileItemReader<CreditBill> flatFileItemReader(){
        FlatFileItemReader<CreditBill> reader = new FlatFileItemReader<>();
        Resource resource = new FileSystemResource("src\\main\\resources\\data\\ch02\\credit_bill_info_02.txt");
        reader.setResource(resource);
        BeanWrapperFieldSetMapper fieldSetMapper = new BeanWrapperFieldSetMapper();
        fieldSetMapper.setTargetType(CreditBill.class);
        DefaultLineMapper<CreditBill> lineMapper = new DefaultLineMapper<>();
        lineMapper.setFieldSetMapper(fieldSetMapper);
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        tokenizer.setDelimiter(",");
        tokenizer.setNames("accountId", "name", "txnAmount", "txnDate", "address");
        lineMapper.setLineTokenizer(tokenizer);
        reader.setLineMapper(lineMapper);
        return reader;
    }

    @Bean
    public CreditBillProcess02 creditBillProcess02(){
        return new CreditBillProcess02();
    }

    @Bean
    public ItemWriter<CreditBill> creditBillDBWritter02(){
        return new CreditBillDBWritter02();
    }

    /**
     * 将 creditBill 写入数据库
     * @return
     */
    @Bean
    public Job creditBillPersistJob(){
        return jobBuilderFactory.get("creditBillPersistJob")
                .start(creditBillPersistStep())
                .build();
    }

    @Bean
    public Step creditBillPersistStep(){
        return stepBuilderFactory.get("creditBillPersistStep")
                .<CreditBill, CreditBill>chunk(2)
                .reader(flatFileItemReader())
                .processor(creditBillProcess02())
                .writer(creditBillDBWritter02())
                .build();
    }
}

注意:

1、需要加上 @EnableBatchProcessing 注解,这个注解的解析,见博客:https://blog.csdn.net/Chris___/article/details/103352103 ;

2、作业 job 和步骤 step 的名字,是在方法名中定义的;

3、CreditBillProcess02 只是简单地打印一句话,CreditBillDBWritter02 则把信用卡账单数据写入到mysql中。

 

三、运行

1、先造几个信用卡账单数据,放在credit_bill_info_02.txt 这个文件中,如下:

 

00000001,zhang1,3500,20190106,shenzhen
00000002,zhang2,300,20190106,shenzhen
00000003,zhang3,200,20190106,shenzhen
00000004,zhang4,500.2,20190106,shenzhen
00000005,zhang5,10,20190106,shenzhen
00000006,zhang6,600,20190106,shenzhen

2、编写一个Springboot的启动类,这个启动类上需要用上注解@SpringBootApplication

另外,如果想多次运行同一个任务(任务名相同),则需要给该任务加上不同的参数

启动类如下:

//如果没有MapperScan这个注解,则每个mapper接口上都必须加上@Mapper 注解
@MapperScan("com.maple.dao.mapper")
@SpringBootApplication
public class Bootstrap {

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Bootstrap.class, args);
        JobLauncher launcher = (JobLauncher)context.getBean("jobLauncher");
        Job job1 = (Job)context.getBean("creditBillPersistJob");
        try{
            JobParametersBuilder paramBuilder = new JobParametersBuilder();
            paramBuilder.addLong("DS", System.currentTimeMillis());
            JobExecution jobExecution = launcher.run(job1, paramBuilder.toJobParameters());
            System.out.println("JobExecution : " + jobExecution.toString());
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

 

在本示例中,我给每个任务加上一个DS的参数,该参数的值是时间戳,所以可多次运行同一个任务

 

3、验证结果

运行程序后,查看数据库中是否正确写入了信用卡账单的信息。

 

 

四、源代码

github : https://github.com/Horven-Jane/springBatchDemo1

 

 

 

 

 

 

 

 

 

 

发布了9 篇原创文章 · 获赞 2 · 访问量 5664
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章