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 对象。
-
通过下面几步实现创建方法:
- 创建JdbcCursorItemReader 对象. 该对象通过打开JDBC游标并持续从结果集中读下一行.
- 配置要使用的数据源.
- 配置从数据库中读数据的SQL 查询语句.
- 配置RowMapper 对象转换单行记录为 T 类型对象. 因为StudentDTO类的属性名与表students的字段名一致,因此可以使用BeanPropertyRowMapper类.
- 最后返回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 对象.
-
通过下面步骤创建方法:
-
创建JdbcPagingItemReader对象.该对象通过jdbc分页读取输入数据.
-
配置使用的数据源 DataSource.
-
配置页大小. 这里设置为1,是因为我们数据表中数据很少,实际应用中应该设置最佳大小提升批处理性能.
-
配置PagingQueryProvider 对象. 该对象指定SQL 查询语句从数据库中获取数据.因为使用H2 内存数据库,这里创建H2PagingQueryProvider 对象.
-
配置RowMapper 对象转换数据库记录转为 T 类型对象. 因为StudentD 类属性与表字段名称一致,我们使用BeanPropertyRowMapper 类.
-
最后返回 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