我正在研究Spring Batch Composite Writer
示例。在这里,我尝试使用compositeItemReader
读取两个表数据,并使用FlatFileItemWriter
写入CSV文件。在执行此操作时,我正在运行主程序,我只看到如下的输出,它只给我对象引用而不是值。
com.common.batch.model.Customer@1615682
com.common.batch.model.Customer@176ad02
com.common.batch.model.Customer@5883fc
com.common.batch.model.Customer@1411cbf
com.common.batch.model.Customer@1c66b53
com.common.batch.model.Customer@f459a4
com.common.batch.model.Customer@293404
com.common.batch.model.Customer@115fae6
com.common.batch.model.Customer@b1298
com.common.batch.model.Customer@f1df22
com.common.batch.model.Customer@c13eca
com.common.batch.model.Customer@1015199
com.common.batch.model.Customer@1943319
com.common.batch.model.Customer@a6bf88
com.common.batch.model.Customer@1687e27
com.common.batch.model.Customer@1bbd50b
com.common.batch.model.Customer@9fd887
com.common.batch.model.Customer@40af64
com.common.batch.model.Customer@baff9a
com.common.batch.model.Customer@e2f388
com.common.batch.model.Customer@10472ac
com.common.batch.model.Customer@10480e1
我希望能够成功查看所有字段值。 Employee.java
public class Employee implements Serializable{
private static final long serialVersionUID = 1L;
private Integer employeeNumber;
private String lastName;
private String firstName;
private String extension;
private String email;
private String officeCode;
private Integer reportsTo;
private String jobTitle;
public Integer getEmployeeNumber() {
return employeeNumber;
}
public void setEmployeeNumber(Integer employeeNumber) {
this.employeeNumber = employeeNumber;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getOfficeCode() {
return officeCode;
}
public void setOfficeCode(String officeCode) {
this.officeCode = officeCode;
}
public Integer getReportsTo() {
return reportsTo;
}
public void setReportsTo(Integer reportsTo) {
this.reportsTo = reportsTo;
}
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
}
Customer.java
public class Customer implements Serializable{
private static final long serialVersionUID = 1L;
private Integer customerNumber;
private String customerName;
private String contactLastName;
private String contactFirstName;
private String phone;
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private String postalCode;
private String country;
private Integer salesRepEmployeeNumber;
private Double creditLimit;
public Integer getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(Integer customerNumber) {
this.customerNumber = customerNumber;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getContactLastName() {
return contactLastName;
}
public void setContactLastName(String contactLastName) {
this.contactLastName = contactLastName;
}
public String getContactFirstName() {
return contactFirstName;
}
public void setContactFirstName(String contactFirstName) {
this.contactFirstName = contactFirstName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Integer getSalesRepEmployeeNumber() {
return salesRepEmployeeNumber;
}
public void setSalesRepEmployeeNumber(Integer salesRepEmployeeNumber) {
this.salesRepEmployeeNumber = salesRepEmployeeNumber;
}
public Double getCreditLimit() {
return creditLimit;
}
public void setCreditLimit(Double creditLimit) {
this.creditLimit = creditLimit;
}
}
job.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:context-datasource.xml" />
<!-- JobRepository and JobLauncher are configuration/setup classes -->
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<!-- Step will need a transaction manager -->
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<job id="compositeJdbcReaderJob" xmlns="http://www.springframework.org/schema/batch">
<step id="compositeJdbcReaderStep" next="compositeJdbcReaderStep2">
<tasklet>
<chunk reader="compositeItemReader" writer="itemWriter" commit-interval="5" />
</tasklet>
</step>
<step id="compositeJdbcReaderStep2">
<tasklet>
<chunk reader="compositeItemReader2" writer="itemWriter2" commit-interval="5" />
</tasklet>
</step>
</job>
<bean id="compositeItemReader" class="com.common.batch.reader.CompositeCursorItemReader">
<property name="unifyingMapper">
<bean class="com.common.batch.mapper.DefaultUnifyingStringItemsMapper" />
</property>
<property name="cursorItemReaders">
<list>
<ref bean="itemReader1" />
</list>
</property>
</bean>
<bean id="compositeItemReader2" class="com.common.batch.reader.CompositeCursorItemReader">
<property name="unifyingMapper">
<bean class="com.common.batch.mapper.DefaultUnifyingStringItemsMapper" />
</property>
<property name="cursorItemReaders">
<list>
<ref bean="itemReader2" />
</list>
</property>
</bean>
<bean id="itemReader1" class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="saveState" value="true" />
<property name="sql">
<value>
<![CDATA[ ${select.sql.customers} ]]>
</value>
</property>
<property name="rowMapper">
<bean class="com.common.batch.mapper.CustomerMapper" />
</property>
</bean>
<bean id="itemReader2" class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="saveState" value="true" />
<property name="sql">
<value>
<![CDATA[ ${select.sql.employees} ]]>
</value>
</property>
<property name="rowMapper">
<bean class="com.common.batch.mapper.EmployeeMapper" />
</property>
</bean>
<bean id="itemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
<property name="resource" value="${output.file.location}" />
<!-- <property name="appendAllowed" value="true" /> -->
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.PassThroughLineAggregator"/>
</property>
</bean>
<bean id="itemWriter2" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
<property name="resource" value="${output.file.location}" />
<property name="appendAllowed" value="true" />
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.PassThroughLineAggregator"/>
</property>
</bean>
</beans>
Main.java
public class CompositeMain {
@SuppressWarnings("resource")
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("job.xml");
JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
Job job = (Job) context.getBean("compositeJdbcReaderJob");
JobExecution execution;
try {
execution = jobLauncher.run(job, new JobParameters());
System.out.println("Job Exit Status : "+ execution.getStatus());
} catch (JobExecutionAlreadyRunningException | JobRestartException
| JobInstanceAlreadyCompleteException | JobParametersInvalidException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
System.out.println("Done !!");
}
}
我希望Flat文件应该写成例如:
firstValue | secondValue | thirdValue ...
根据迈克尔的建议,我在下面开发了XML文件:
<bean id="itemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
<property name="resource" value="${output.file.location}" />
<!-- <property name="appendAllowed" value="true" /> -->
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter" value="|" />
<property name="fieldExtractor">
<!-- Extractor which returns the value of beans property through reflection -->
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="customerNumber,customerName,contactLastName,contactFirstName,phone,addressLine1,addressLine2,city,state,postalCode,country,salesRepEmployeeNumber,creditLimit" />
</bean>
</property>
</bean>
</property>
</bean>
<bean id="itemWriter2" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
<property name="resource" value="${output.file.location}" />
<property name="appendAllowed" value="true" />
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter" value="|" />
<property name="fieldExtractor">
<!-- Extractor which returns the value of beans property through reflection -->
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="employeeNumber,lastName,firstName,extension,email,officeCode,reportsTo,jobTitle" />
</bean>
</property>
</bean>
</property>
</bean>
答案 0 :(得分:3)
您正在使用PassThroughLineAggregator(强调我的)
LineAggregator接口的最基本实现是 PassThroughLineAggregator,它只是假设对象是 已经是一个字符串,或其字符串表示可以接受 的写强>
更改为特定的LineAggregator或调整对象的toString方法以输出您希望的方式