Skip to main content
 首页 » 编程设计

Spring Batch 读数据库教程

2022年07月19日154exmyth

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 类实现分页方式读取数据。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/101867252