Spring Batch 读数据库教程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/neweastsun/article/details/101867252

Spring Batch 读数据库教程

实际Spring Batch项目中从数据库中读取信息很常用,本文介绍如何从数据库中读取数据,通过游标或分页方式读取。

示例需求说明

示例场景是在线学习应用,通过Spring Batch从数据库中导出学生信息,学生表的字段如下:

email_address 列为学生邮件地址 contains the email address of the student.
name 列为学生姓名.
purchased_package 列为学生购买的学习包.

实现Spring batch批job,第一步是为job提供数据。本例中是数据从库中读取学生信息并转换为StudentDTO对象。

StudentDTO 类代码如下:

@Data
public class StudentDTO {
    private String emailAddress;
    private String name;
    private String purchasedPackage;
}

使用数据库游标读信息

通过配置ItemReader bean为批job提供输入数据。配置ItemReader需要三个步骤:

  • 使用 @Configuration 注解创建配置类。批job的配置类注意配置job以及job流程bean.

  • 创建方法配置ItemReader bean, 该方法带DataSource对象作为参数并返回ItemReader 对象。

  • 通过下面几步实现创建方法:

    1. 创建JdbcCursorItemReader 对象. 该对象通过打开JDBC游标并持续从结果集中读下一行.
    2. 配置要使用的数据源.
    3. 配置从数据库中读数据的SQL 查询语句.
    4. 配置RowMapper 对象转换单行记录为 T 类型对象. 因为StudentDTO类的属性名与表students的字段名一致,因此可以使用BeanPropertyRowMapper类.
    5. 最后返回JdbcCursorItemReader 对象.

配置类代码如下:

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
 
import javax.sql.DataSource;
 
@Configuration
public class DatabaseToXmlFileJobConfig {
 
    private static final String QUERY_FIND_STUDENTS =
            "SELECT " +
                "email_address, " +
                "name, " +
                "purchased_package " +
            "FROM STUDENTS " +
            "ORDER BY email_address ASC";
 
    @Bean
    ItemReader<StudentDTO> databaseXmlItemReader(DataSource dataSource) {
        JdbcCursorItemReader<StudentDTO> databaseReader = new JdbcCursorItemReader<>();
 
        databaseReader.setDataSource(dataSource);
        databaseReader.setSql(QUERY_FIND_STUDENTS);
        databaseReader.setRowMapper(new BeanPropertyRowMapper<>(StudentDTO.class));
 
        return databaseReader;
    }
}

该配置从数据库中读取所有数据至内存,下面我们讲解如何实现分页读取。

分页方式读信息

实现分页读ItemReaderbean,配置需要下列步骤:

  • 通过 @Configuration 注解创建配置类.配置批job及流程.

  • 创建方法配置ItemReader bean, 该方法带DataSource对象作为参数并返回ItemReader 对象.

  • 通过下面步骤创建方法:

  1. 创建JdbcPagingItemReader对象.该对象通过jdbc分页读取输入数据.

  2. 配置使用的数据源 DataSource.

  3. 配置页大小. 这里设置为1,是因为我们数据表中数据很少,实际应用中应该设置最佳大小提升批处理性能.

  4. 配置PagingQueryProvider 对象. 该对象指定SQL 查询语句从数据库中获取数据.因为使用H2 内存数据库,这里创建H2PagingQueryProvider 对象.

  5. 配置RowMapper 对象转换数据库记录转为 T 类型对象. 因为StudentD 类属性与表字段名称一致,我们使用BeanPropertyRowMapper 类.

  6. 最后返回 JdbcPagingItemReader 对象.

代码如下:

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.database.JdbcPagingItemReader;
import org.springframework.batch.item.database.Order;
import org.springframework.batch.item.database.PagingQueryProvider;
import org.springframework.batch.item.database.support.H2PagingQueryProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
 
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
 
@Configuration
public class DatabaseToCsvFileJobConfig {
 
    @Bean
    ItemReader<StudentDTO> databaseCsvItemReader(DataSource dataSource) {
        JdbcPagingItemReader<StudentDTO> databaseReader = new JdbcPagingItemReader<>();
 
        databaseReader.setDataSource(dataSource);
        databaseReader.setPageSize(1);
 
        PagingQueryProvider queryProvider = createQueryProvider();
        databaseReader.setQueryProvider(queryProvider);
 
        databaseReader.setRowMapper(new BeanPropertyRowMapper<>(StudentDTO.class));
 
        return databaseReader;
    }
 
    private PagingQueryProvider createQueryProvider() {
        H2PagingQueryProvider queryProvider = new H2PagingQueryProvider();
 
        queryProvider.setSelectClause("SELECT email_address, name, purchased_package");
        queryProvider.setFromClause("FROM students");
        queryProvider.setSortKeys(sortByEmailAddressAsc());
 
        return queryProvider;
    }
 
    private Map<String, Order> sortByEmailAddressAsc() {
        Map<String, Order> sortConfiguration = new HashMap<>();
        sortConfiguration.put("email_address", Order.ASCENDING);
        return sortConfiguration;
    }
}

总结

通过JdbcCursorItemReader 实现jdbc游标方式读取数据,通过JdbcPagingItemReader 类实现分页方式读取数据。

猜你喜欢

转载自blog.csdn.net/neweastsun/article/details/101867252