接上一章,Spring Batch本身提供了许多开箱即用的ItemReader与ItemWriter实现。Spring Batch 4针对这些组件又提供了Builder实现,用户可以很方便的通过Builder模式来使用这些组件。
本章,我们重点讨论以下几种ItemReader和ItemWriter的使用。
ItemReader
- FlatFileItemReader
对于FlatFileItemReader,官方示例已给出代码实现。我们这里不多赘述。
Reads from a flat file. Includes ItemStream and Skippable functionality
@Bean
public FlatFileItemReader<User> flatFileItemReader() {
FlatFileItemReader<User> reader = new FlatFileItemReader<>();
DefaultLineMapper<User> lineMapper = new DefaultLineMapper<User>() {
{
setLineTokenizer(new DelimitedLineTokenizer() {
{
setNames(new String[]{"firstName", "lastName"});
}
});
setFieldSetMapper(new BeanWrapperFieldSetMapper<User>() {
{
setTargetType(User.class);
}
});
}
};
reader.setResource(new ClassPathResource("sample-data.csv"));
reader.setLineMapper(lineMapper);
return reader;
}
- JpaPagingItemReader
Given a JPQL statement, pages through the rows, such that large datasets can be read without running out of memory.
以JPQL方式读取海量数据库记录,为避免内存泄漏,以分页方式读取。
@Bean(destroyMethod = "")
@Qualifier("jpaPagingItemReader")
public ItemReader<User> jpaPagingItemReader() {
JpaPagingItemReader<User> reader = new JpaPagingItemReader<User>();
String sqlQuery = "select * from user where id like :limit ";
JpaNativeQueryProvider<User> queryProvider = new JpaNativeQueryProvider<User>();
queryProvider.setSqlQuery(sqlQuery);
queryProvider.setEntityClass(User.class);
reader.setEntityManagerFactory(emf);
reader.setPageSize(3);
reader.setQueryProvider(queryProvider);
reader.setParameterValues(Collections.<String, Object>singletonMap("limit", "%"));
reader.setSaveState(true);
return reader;
}
- RepositoryItemReader
Given a Spring Data PagingAndSortingRepository object, a Sort, and the name of method to execute, returns items provided by the Spring Data repository implementation.
以Spring Data JPA(Spring Data Repository)方式读取数据,传入参数包含:PagingAndSortingRepository对象,结果集排序方式,调用目标方法等。返回Spring Data JPA方法实现执行结果。
比如,对于UserReaderRepository:
public interface UserReaderRepository extends PagingAndSortingRepository<User, Long> {
@Override
Page<User> findAll(Pageable pageable);
Page<User> findAllByFirstNameLike(String firstName, Pageable pageable);
}
接口中定义findAllByFirstNameLike
方法,查询FirstName以特定字符开始的数据库记录,因此,我们的RepositoryItemReader
定义如下:
@Bean
@Qualifier("repositoryItemReaderWithParams")
public RepositoryItemReader<User> repositoryItemReaderWithParams() {
Map<String, Sort.Direction> map = new HashMap<>();
map.put("id", Sort.Direction.DESC);
List<String> params = new ArrayList();
params.add("i%");
RepositoryItemReader<User> repositoryItemReader = new RepositoryItemReader<>();
repositoryItemReader.setRepository(userReaderRepository);
repositoryItemReader.setPageSize(5);
repositoryItemReader.setMethodName("findAllByFirstNameLike");
repositoryItemReader.setArguments(params);
repositoryItemReader.setSort(map);
return repositoryItemReader;
}
ItemWriter
- JdbcBatchItemWriter
Uses batching features from a PreparedStatement, if available, and can take rudimentary steps to locate a failure during a flush.
利用PreparedStatement批处理特性保存数据。
@Bean
@Qualifier("jdbcBatchItemWriter")
public JdbcBatchItemWriter<People> jdbcBatchItemWriter() {
JdbcBatchItemWriter<People> writer = new JdbcBatchItemWriter<>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
writer.setSql("insert into people (person_id, first_name, last_name) VALUES (uuid(), :firstName, :lastName)");
writer.setDataSource(w_dataSource);
return writer;
}
- RepositoryItemWriter
Given a Spring Data CrudRepository implementation, items are saved through the method specified in the configuration.
调用Spring Data JPA (Spring Data CrudRepository)指定方法实现,将数据保存到目标数据库中。比如,我们定义PeopleCrudRepository接口:
public interface PeopleCrudRepository extends CrudRepository<People, Long> {
}
我们调用CrudRepository中的默认save方法实现。
@Bean
@Qualifier("repositoryItemWriter")
public RepositoryItemWriter<People> repositoryItemWriter() {
RepositoryItemWriter<People> peopleRepositoryItemWriter = new RepositoryItemWriter<>();
peopleRepositoryItemWriter.setRepository(peopleCrudRepository);
peopleRepositoryItemWriter.setMethodName("save");
return peopleRepositoryItemWriter;
}
更多源码请参考:
https://github.com/ypmc/spring-cloud/tree/master/spring-batch