Spring Batch - compositeItemReader and compositeItemWritter examples - Unable to print both tables data in same XML/CSV file

谁说我不能喝 提交于 2019-12-23 05:12:41

问题


I am developing the Composite Reader and Writter example. I am able to successfully developed the code, but when trying to run the code I am getting only one tables data, I don't see other tables data is coming in CSV file. Please guide.

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;
    // setters and getters

    @Override
public String toString() {
    return employeeNumber + "|"+ lastName + "|" + firstName + "|"+ extension + 
            "|" + email + "|" + officeCode+ "|" + reportsTo + "|" + jobTitle;
}
}

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;
    // setters and getters

    @Override
public String toString() {
    return customerNumber + "|" + customerName + "|" + contactLastName + "|" + contactFirstName + "|" + 
            phone+ "|" + addressLine1 + "|" + addressLine2 + "|" + city + "|" + state+ "|" + postalCode + "|" + 
            country+ "|" + salesRepEmployeeNumber + "|" + creditLimit;
}
}

jdbc-composite-item-reader-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">
            <tasklet>
                <chunk reader="compositeItemReader" writer="itemWriter" commit-interval="5"></chunk>
            </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" />
                <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 * FROM 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 * FROM 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="file:csv/employees.txt" />

        <property name="lineAggregator">
            <bean class="org.springframework.batch.item.file.transform.PassThroughLineAggregator"/>
        </property>
    </bean>
</beans>

EmployeeMapper.java

public class EmployeeMapper implements RowMapper<Employee>{

    @Override
    public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
        Employee employee = new Employee();
        employee.setEmployeeNumber(rs.getInt("employeeNumber"));
        employee.setLastName(rs.getString("lastName"));
        employee.setFirstName(rs.getString("firstName"));
        employee.setExtension(rs.getString("extension"));
        employee.setEmail(rs.getString("email"));
        employee.setOfficeCode(rs.getString("officeCode"));
        employee.setReportsTo(rs.getInt("reportsTo"));
        employee.setJobTitle(rs.getString("jobTitle"));

        return employee;
    }
}

CustomerMapper.java

public class CustomerMapper implements RowMapper<Customer>{

    @Override
    public Customer mapRow(ResultSet rs, int rowNum) throws SQLException {
        Customer customer = new Customer();
        customer.setCustomerNumber(rs.getInt("customerNumber"));
        customer.setCustomerName(rs.getString("customerName"));
        customer.setContactLastName(rs.getString("contactLastName"));
        customer.setContactFirstName(rs.getString("contactFirstName"));
        customer.setPhone(rs.getString("phone"));
        customer.setAddressLine1(rs.getString("addressLine1"));
        customer.setAddressLine2(rs.getString("addressLine2"));
        customer.setCity(rs.getString("city"));
        customer.setState(rs.getString("state"));
        customer.setPostalCode(rs.getString("postalCode"));
        customer.setCountry(rs.getString("country"));
        customer.setSalesRepEmployeeNumber(rs.getInt("salesRepEmployeeNumber"));
        customer.setCreditLimit(rs.getDouble("creditLimit"));

        return customer;
    }
}

CompositeMain.java

public class CompositeMain {
    @SuppressWarnings("resource")
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("composite/jdbc-composite-item-reader-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 !!");
    }
}

CompositeCursorItemReader.java

public class CompositeCursorItemReader<T> implements ItemStreamReader<T> {

    private List<AbstractCursorItemReader<?>> cursorItemReaders;

    private UnifyingItemsMapper<T> unifyingMapper;

    @Override
    public T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
        // read from all registered readers
        List items = new ArrayList();
        for (AbstractCursorItemReader<?> cursorItemReader : cursorItemReaders) {
            items.add(cursorItemReader.read());
        }
        // delegate to mapper
        return unifyingMapper.mapItems(items);
    }

    @Override
    public void update(ExecutionContext executionContext) {
        for (ItemStream itemStream : cursorItemReaders) {
            itemStream.update(executionContext);
        }
    }

    @Override
    public void close() throws ItemStreamException {
        for (ItemStream itemStream : cursorItemReaders) {
            itemStream.close();
        }
    }

    @Override
    public void open(ExecutionContext executionContext) throws ItemStreamException {
        for (ItemStream itemStream : cursorItemReaders) {
            itemStream.open(executionContext);
        }
    }

    public void setUnifyingMapper(UnifyingItemsMapper<T> mapper) {
        this.unifyingMapper = mapper;
    }

    public void setCursorItemReaders(List<AbstractCursorItemReader<?>> cursorItemReaders) {
        this.cursorItemReaders = cursorItemReaders;
    }
}

When I see output I only see one tables data:

121|Baane Mini Imports|Bergulfsen|Jonas |07-98 9555|Erling Skakkes gate 78|null|Stavern|null|4110|Norway|1504|81700.01102|Bondur|Gerard|x5408|gbondur@classicmodelcars.com|4|1056|Sale Manager (EMEA)
124|Mini Gifts Distributors Ltd.|Nelson|Susan|4155551450|5677 Strong St.|null|San Rafael|CA|97562|USA|1165|210500.01143|Bow|Anthony|x5428|abow@classicmodelcars.com|1|1056|Sales Manager (NA)
125|Havel & Zbyszek Co|Piestrzeniewicz|Zbyszek |(26) 642-7555|ul. Filtrowa 68|null|Warszawa|null|01-012|Poland|0|0.01165|Jennings|Leslie|x3291|ljennings@classicmodelcars.com|1|1143|Sales Rep
128|Blauer See Auto, Co.|Keitel|Roland|+49 69 66 90 2555|Lyonerstr. 34|null|Frankfurt|null|60528|Germany|1504|59700.01166|Thompson|Leslie|x4065|lthompson@classicmodelcars.com|1|1143|Sales Rep
129|Mini Wheels Co.|Murphy|Julie|6505555787|5557 North Pendale Street|null|San Francisco|CA|94217|USA|1165|64600.01188|Firrelli|Julie|x2173|jfirrelli@classicmodelcars.com|2|1143|Sales Rep
131|Land of Toys Inc.|Lee|Kwai|2125557818|897 Long Airport Avenue|null|NYC|NY|10022|USA|1323|114900.01216|Patterson|Steve|x4334|spatterson@classicmodelcars.com|2|1143|Sales Rep
141|Euro+ Shopping Channel|Freyre|Diego |(91) 555 94 44|C/ Moralzarzal, 86|null|Madrid|null|28034|Spain|1370|227600.01286|Tseng|Foon Yue|x2248|ftseng@classicmodelcars.com|3|1143|Sales Rep
144|Volvo Model Replicas, Co|Berglund|Christina |0921-12 3555|Berguvsvägen  8|null|Luleå|null|S-958 22|Sweden|1504|53100.01323|Vanauf|George|x4102|gvanauf@classicmodelcars.com|3|1143|Sales Rep
145|Danish Wholesale Imports|Petersen|Jytte |31 12 3555|Vinbæltet 34|null|Kobenhavn|null|1734|Denmark|1401|83400.01337|Bondur|Loui|x6493|lbondur@classicmodelcars.com|4|1102|Sales Rep
146|Saveley & Henriot, Co.|Saveley|Mary |78.32.5555|2, rue du Commerce|null|Lyon|null|69004|France|1337|123900.01370|Hernandez|Gerard|x2028|ghernande@classicmodelcars.com|4|1102|Sales Rep
148|Dragon Souveniers, Ltd.|Natividad|Eric|+65 221 7555|Bronz Sok.|Bronz Apt. 3/6 Tesvikiye|Singapore|null|079903|Singapore|1621|103800.01401|Castillo|Pamela|x2759|pcastillo@classicmodelcars.com|4|1102|Sales Rep
151|Muscle Machine Inc|Young|Jeff|2125557413|4092 Furth Circle|Suite 400|NYC|NY|10022|USA|1286|138500.01501|Bott|Larry|x2311|lbott@classicmodelcar

I've couple of questions now:

  1. How we can print both tables data into single file?
  2. How we can print both tables data into separate files?
  3. How we can print actual values rather than reference for lbott@classicmodelcar FK relationship tables?

Please let me know if you need any other information for solving the issue. Expecting feedback from experts.

The Entity Relationship..


回答1:


Re #3, As per Entity Relationship (ER) I think you need to create model class for the Payment like below: Please make sure created model classes for all tables of ER diagram.

Payment.java

public class Payment implements Serializable{
    private static final long serialVersionUID = 1L;

    private Integer customerNumber;
    private String checkNumber;
    private Date paymentDate;
    private Double amount;
        // setters and getters

        @Override
    public String toString() {
        return customerNumber + "|"+ checkNumber + "|" + paymentDate + "|"+ amount ;
    }
}

This is happening because you've not created separate ItemWritter for each table to be get written in file. You need to do following things:'

  1. create another FlatFileItemWriter say <bean id="itemWriter2" .... />
  2. Also you need to create another JdbcCursorItemReader like say <bean id="itemReader2" class="org.springframework.batch.item.database.JdbcCursorItemReader">
  3. Also you need to create separate CompositeCursorItemReader like say <bean id="compositeItemReader2" class="com.common.batch.reader.CompositeCursorItemReader">
  4. Also you need to define like below in order to call next step

        <step id="compositeJdbcReaderStep2">
            <tasklet>
                <chunk reader="compositeItemReader2" writer="itemWriter2" commit-interval="5" />
            </tasklet>
        </step>
    </job>
    


来源:https://stackoverflow.com/questions/36373455/spring-batch-compositeitemreader-and-compositeitemwritter-examples-unable-to

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!