In this example, we’ll see how to read the data from database and write it into XML file. For that we’ll use StaxEventItemWriter — implementation of ItemWriter which uses StAX and Marshaller for serializing object to XML. This item writer also provides restart, statistics and transaction features by implementing corresponding interfaces. The implementation is not thread-safe.
Customer.java
@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class Customer {
private Long id;
private String firstName;
private String lastName;
private String birthdate;
}
CustomerRowMapper.java
public class CustomerRowMapper implements RowMapper<Customer> {
@Override
public Customer mapRow(ResultSet rs, int rowNum) throws SQLException {
return Customer.builder().id(rs.getLong("id"))
.firstName(rs.getString("firstName"))
.lastName(rs.getString("lastName"))
.birthdate(rs.getString("birthdate")).build();
}
}
JobConfigurations.java
@Configuration
public class JobConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private DataSource dataSource;
@Bean
public JdbcPagingItemReader<Customer> customerPagingItemReader(){
// reading database records using JDBC in a paging fashion
JdbcPagingItemReader<Customer> reader = new JdbcPagingItemReader<>();
reader.setDataSource(this.dataSource);
reader.setFetchSize(1000);
reader.setRowMapper(new CustomerRowMapper());
// Sort Keys
Map<String, Order> sortKeys = new HashMap<>();
sortKeys.put("id", Order.ASCENDING);
// MySQL implementation of a PagingQueryProvider using database specific features.
MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
queryProvider.setSelectClause("id, firstName, lastName, birthdate");
queryProvider.setFromClause("from customer");
queryProvider.setSortKeys(sortKeys);
reader.setQueryProvider(queryProvider);
return reader;
}
@SuppressWarnings("rawtypes")
@Bean
public StaxEventItemWriter<Customer> customerItemWriter() throws Exception{
String customerOutputPath = File.createTempFile("customerOutput", ".out").getAbsolutePath();
System.out.println(">> Output Path = "+customerOutputPath);
Map<String, Class> aliases = new HashMap<>();
aliases.put("customer", Customer.class);
XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.setAliases(aliases);
// StAX and Marshaller for serializing object to XML.
StaxEventItemWriter<Customer> writer = new StaxEventItemWriter<>();
writer.setRootTagName("customers");
writer.setMarshaller(marshaller);
writer.setResource(new FileSystemResource(customerOutputPath));
writer.afterPropertiesSet();
return writer;
}
@Bean
public Step step1() throws Exception {
return stepBuilderFactory.get("step1")
.<Customer, Customer>chunk(100)
.reader(customerPagingItemReader())
.writer(customerItemWriter())
.build();
}
@Bean
public Job job() throws Exception {
return jobBuilderFactory.get("job")
.start(step1())
.build();
}
}
MainApp.java
@SpringBootApplication
@EnableBatchProcessing
public class XmlFileOutputApplication implements CommandLineRunner{
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job job;
public static void main(String[] args) {
SpringApplication.run(XmlFileOutputApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
JobParameters jobParameters = new JobParametersBuilder()
.addString("JobId", String.valueOf(System.currentTimeMillis()))
.addDate("date", new Date())
.addLong("time",System.currentTimeMillis()).toJobParameters();
JobExecution execution = jobLauncher.run(job, jobParameters);
System.out.println("STATUS :: "+execution.getStatus());
}
}
application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.batch.initialize-schema=always
spring.batch.job.enabled=false
schema.sql
CREATE TABLE `test`.`customer` (
`id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
`firstName` VARCHAR(255) NULL,
`lastName` VARCHAR(255) NULL,
`birthdate` VARCHAR(255) NULL,
PRIMARY KEY (`id`)
) AUTO_INCREMENT=1;
data-mysql.sql
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('1', 'John', 'Doe', '10-10-1952 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('2', 'Amy', 'Eugene', '05-07-1985 17:10:00');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('3', 'Laverne', 'Mann', '11-12-1988 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('4', 'Janice', 'Preston', '19-02-1960 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('5', 'Pauline', 'Rios', '29-08-1977 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('6', 'Perry', 'Burnside', '10-03-1981 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('7', 'Todd', 'Kinsey', '14-12-1998 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('8', 'Jacqueline', 'Hyde', '20-03-1983 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('9', 'Rico', 'Hale', '10-10-2000 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('10', 'Samuel', 'Lamm', '11-11-1999 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('11', 'Robert', 'Coster', '10-10-1972 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('12', 'Tamara', 'Soler', '02-01-1978 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('13', 'Justin', 'Kramer', '19-11-1951 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('14', 'Andrea', 'Law', '14-10-1959 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('15', 'Laura', 'Porter', '12-12-2010 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('16', 'Michael', 'Cantu', '11-04-1999 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('17', 'Andrew', 'Thomas', '04-05-1967 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('18', 'Jose', 'Hannah', '16-09-1950 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('19', 'Valerie', 'Hilbert', '13-06-1966 10:10:10');
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('20', 'Patrick', 'Durham', '12-10-1978 10:10:10');
Console Output —
<?xml version=”1.0" encoding=”UTF-8"?><customers><customer><id>1</id><firstName>John</firstName><lastName>Doe</lastName><birthdate>10–10–1952 10:10:10</birthdate></customer><customer><id>2</id><firstName>Amy</firstName><lastName>Eugene</lastName><birthdate>05–07–1985 17:10:00</birthdate></customer><customer><id>3</id><firstName>Laverne</firstName><lastName>Mann</lastName><birthdate>11–12–1988 10:10:10</birthdate></customer><customer><id>4</id><firstName>Janice</firstName><lastName>Preston</lastName><birthdate>19–02–1960 10:10:10</birthdate></customer><customer><id>5</id><firstName>Pauline</firstName><lastName>Rios</lastName><birthdate>29–08–1977 10:10:10</birthdate></customer><customer><id>6</id><firstName>Perry</firstName><lastName>Burnside</lastName><birthdate>10–03–1981 10:10:10</birthdate></customer><customer><id>7</id><firstName>Todd</firstName><lastName>Kinsey</lastName><birthdate>14–12–1998 10:10:10</birthdate></customer><customer><id>8</id><firstName>Jacqueline</firstName><lastName>Hyde</lastName><birthdate>20–03–1983 10:10:10</birthdate></customer><customer><id>9</id><firstName>Rico</firstName><lastName>Hale</lastName><birthdate>10–10–2000 10:10:10</birthdate></customer><customer><id>10</id><firstName>Samuel</firstName><lastName>Lamm</lastName><birthdate>11–11–1999 10:10:10</birthdate></customer><customer><id>11</id><firstName>Robert</firstName><lastName>Coster</lastName><birthdate>10–10–1972 10:10:10</birthdate></customer><customer><id>12</id><firstName>Tamara</firstName><lastName>Soler</lastName><birthdate>02–01–1978 10:10:10</birthdate></customer><customer><id>13</id><firstName>Justin</firstName><lastName>Kramer</lastName><birthdate>19–11–1951 10:10:10</birthdate></customer><customer><id>14</id><firstName>Andrea</firstName><lastName>Law</lastName><birthdate>14–10–1959 10:10:10</birthdate></customer><customer><id>15</id><firstName>Laura</firstName><lastName>Porter</lastName><birthdate>12–12–2010 10:10:10</birthdate></customer><customer><id>16</id><firstName>Michael</firstName><lastName>Cantu</lastName><birthdate>11–04–1999 10:10:10</birthdate></customer><customer><id>17</id><firstName>Andrew</firstName><lastName>Thomas</lastName><birthdate>04–05–1967 10:10:10</birthdate></customer><customer><id>18</id><firstName>Jose</firstName><lastName>Hannah</lastName><birthdate>16–09–1950 10:10:10</birthdate></customer><customer><id>19</id><firstName>Valerie</firstName><lastName>Hilbert</lastName><birthdate>13–06–1966 10:10:10</birthdate></customer><customer><id>20</id><firstName>Patrick</firstName><lastName>Durham</lastName><birthdate>12–10–1978 10:10:10</birthdate></customer></customers>