这种实现只适用于小数据集,因为数据通过一次批处理查询读取,并将整个结果列表存储在内存中.而且,它不是线程安全的.
- 在内存有限的环境中可能会导致内存不足
- 可能会导致性能问题.我们将等待,直到通过一次调用从DB加载数千条记录
Solution 1, 100
protected void doOpen() throws Exception {
...
Query query = createQuery();
if (this.parameterValues != null) {
this.parameterValues.forEach(query::setParameter);
}
this.iterator = query.getResultStream().iterator();
}
例如,Hibernate在5.2版中引入了Query.getResultStream()
方法.
protected ItemReader<Foo> getItemReader() throws Exception {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
String jpqlQuery = "from Foo";
JpaCursorItemReader<Foo> itemReader = new JpaCursorItemReader<>();
itemReader.setQueryString(jpqlQuery);
itemReader.setEntityManagerFactory(factoryBean.getObject());
itemReader.afterPropertiesSet();
itemReader.setSaveState(true);
return itemReader;
}
Solution 2, 100
ItemReader用于读取建立在JPA之上的数据库记录.
它执行JPQL setQueryString(字符串)以检索请求的
分页的性能取决于JPA实现和
设置相当大的页面大小并使用提交间隔
为了减少大结果的内存使用,持久性
在调用之间,实现是线程安全的
Solution 3, 100
一种项目阅读器,利用
读卡器的性能取决于存储库
必须为读卡器配置分页和排序存储库
此实现在调用之间是线程安全的
创建示例:
PagingAndSortingRepository<Foo, Long> repository = FooRepository<>();
RepositoryItemReader<Foo> reader = new RepositoryItemReader<>();
reader.setRepository(repository ); //The PagingAndSortingRepository implementation used to read input from.
reader.setMethodName("findByName"); //Specifies what method on the repository to call.
reader.setArguments(arguments); // Arguments to be passed to the data providing method.
通过生成器创建:
PagingAndSortingRepository<Foo, Long> repository = new FooRepository<>();
new RepositoryItemReaderBuilder<>().repository(repository)
.methodName("findByName")
.arguments(new ArrayList<>())
.build()
更多用法示例:RepositoryItemReaderTests和RepositoryItemReaderIntegrationTests
Summarise: