我有以下要求,但我无法决定采取的方法:
我需要将数据写入固定格式的输出文件,其中每条记录跨越多行,如下所示:
000120992599999990000000000000009291100000000000000000000000010000
000000000000000000000006050052570009700000050000990494920000111100
ABCDE:WXYZ 0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
000000000000000000000006050052730005700001100000090494920000221200
ABCDE:WXYZ 0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
000000000000000000000006050113110009700000000000000494920000311100
ABCDE:WXYZ 0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
000012099259999999000000000000000929110000000000000000000000001000
这是以上示例中的一条记录:
000000000000000000000006050052570009700000050000990494920000111100
ABCDE:WXYZ 0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
descriptiongoesheredescriptiongoesheredescriptiongoesher0200
第一行和最后一行分别是页眉和页脚。 每条记录的第一行包含几个细节。 第二行有一些其他的空格细节。
我有一个很长的描述字段,我需要将其划分为56个字符的部分,然后追加记录的第3行以上的部分。
所以在一些记录中,这可能只是一行,而在某些记录中也可能是三行。
我需要有关如何在上面的场景中设计我的项目编写者的指导。
的Nik
答案 0 :(得分:6)
官方spring-batch-samples中有一个多行记录编写器示例,搜索multiline.xml
和MultiLineTradeItemWriter
它基本上是通常的委托原则,你只需要一个合适的域对象,可以使用那些1..n中间行的列表
public class MultiLineTradeItemWriter implements ItemWriter<Trade>, ItemStream {
private FlatFileItemWriter<String> delegate;
public void write(List<? extends Trade> items) throws Exception {
List<String> lines = new ArrayList<String>();
for (Trade t : items) {
lines.add("BEGIN");
lines.add("INFO," + t.getIsin() + "," + t.getCustomer());
lines.add("AMNT," + t.getQuantity() + "," + t.getPrice());
lines.add("END");
}
this.delegate.write(lines);
}
}
答案 1 :(得分:0)
你可以在CustomExtractor中完成。
例如:
public Object[] extract(T item) {
List<Object> values = new ArrayList<Object>();
BeanWrapper bw = new BeanWrapperImpl(item);
for (String propertyName : this.names) {
values.add( bw.getPropertyValue(propertyName) + "\r\n");
}
return values.toArray();
}
答案 2 :(得分:0)
我在向数据库写入多行时遇到了类似的问题。由于作业步骤将创建项目列表,如何将列表从处理器返回到编写器?这将创建一个列表列表,并且Writer中的doWrite方法未设置为处理该场景。
我正在使用1.2.0 spring-boot-starter-parent(它给我spring-core 4.1.3)和hibernate(4.3.7),在我的情况下我有'应收账款',每1个我从csv文件中读取的应收款,然后我可能需要更新或插入许多应收款到我的表中。我也在使用HibernateItemWriter。
我的解决方案是扩展HibernateItemWriter。 sessionFactory字段是私有的,所以我通过构造函数传递它,也使用setter(以使现有代码适应)。所以我的原始代码(适用于单个“应收款”)最初看起来像这样:
@Bean
public ItemWriter<Receivable> recivableWriter() {
HibernateItemWriter<Receivable> hibernateItemWriter = new HibernateItemWriter<Receivable>(){{ setSessionFactory(sessionFactory); }};
return hibernateItemWriter;
}
在扩展HibernateItemWriter并修改我的处理器以返回List之后,我的代码改为:
@Bean
public ItemWriter<List<Receivable>> receivableWriter() {
HibernateListItemWriter<List<Receivable>> hibernateItemWriter = new HibernateListItemWriter<List<Receivable>>(this.sessionFactory){{ setSessionFactory(sessionFactory); }};
return hibernateItemWriter;
}
我的扩展类看起来像这样(我可能会清理它,但这是我的初始传递。我也希望sessionFactory和clearSession字段不是私有的)
package com.work;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.SessionFactory;
public class HibernateListItemWriter<Receivable> extends org.springframework.batch.item.database.HibernateItemWriter<Receivable> {
public HibernateListItemWriter(SessionFactory sessionFactory) {
super();
this.sessionFactory = sessionFactory;
}
private SessionFactory sessionFactory;
private boolean clearSession = true;
@Override
public void write(List items) {
List<Receivable> unwrappedItems = new ArrayList<Receivable>();
List<List<Receivable>> wrappedItems = (List<List<Receivable>>)items;
for (List<Receivable> singleList: wrappedItems) {
unwrappedItems.addAll(singleList);
}
doWrite(sessionFactory, unwrappedItems);
sessionFactory.getCurrentSession().flush();
if(clearSession) {
sessionFactory.getCurrentSession().clear();
}
}
}
向grepcode.com致敬,让生活更轻松。