В этом примере я покажу вам, как записывать данные в несколько мест назначения и как мы можем записывать данные в JSON и XML.
В этом примере я использую MySQL, однако вы можете использовать любую базу данных по вашему выбору. Пожалуйста, убедитесь, что создали эквивалентную схему и данные в этой БД.
MySQL
1
CREATE TABLE `test`.`customer` (
2
`id` MEDIUMINT(8) UNSIGNED NOT NULL,
3
`firstName` VARCHAR(255) NULL,
4
`lastName` VARCHAR(255) NULL,
5
`birthdate` VARCHAR(255) NULL,
6
PRIMARY KEY (`id`)
7
);
8
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('1', 'John', 'Doe', '10-10-1952 10:10:10');
10
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('2', 'Amy', 'Eugene', '05-07-1985 17:10:00');
11
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('3', 'Laverne', 'Mann', '11-12-1988 10:10:10');
12
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('4', 'Janice', 'Preston', '19-02-1960 10:10:10');
13
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('5', 'Pauline', 'Rios', '29-08-1977 10:10:10');
14
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('6', 'Perry', 'Burnside', '10-03-1981 10:10:10');
15
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('7', 'Todd', 'Kinsey', '14-12-1998 10:10:10');
16
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('8', 'Jacqueline', 'Hyde', '20-03-1983 10:10:10');
17
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('9', 'Rico', 'Hale', '10-10-2000 10:10:10');
18
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('10', 'Samuel', 'Lamm', '11-11-1999 10:10:10');
19
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('11', 'Robert', 'Coster', '10-10-1972 10:10:10');
20
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('12', 'Tamara', 'Soler', '02-01-1978 10:10:10');
21
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('13', 'Justin', 'Kramer', '19-11-1951 10:10:10');
22
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('14', 'Andrea', 'Law', '14-10-1959 10:10:10');
23
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('15', 'Laura', 'Porter', '12-12-2010 10:10:10');
24
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('16', 'Michael', 'Cantu', '11-04-1999 10:10:10');
25
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('17', 'Andrew', 'Thomas', '04-05-1967 10:10:10');
26
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('18', 'Jose', 'Hannah', '16-09-1950 10:10:10');
27
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('19', 'Valerie', 'Hilbert', '13-06-1966 10:10:10');
28
INSERT INTO `test`.`customer` (`id`, `firstName`, `lastName`, `birthdate`) VALUES ('20', 'Patrick', 'Durham', '12-10-1978 10:10:10');
Вы также можете насладиться: Введение в Spring Batch
Основной класс для начала исполнения.
Джава
xxxxxxxxxx
1
package com.example;
2
import java.util.Date;
4
import org.springframework.batch.core.Job;
6
import org.springframework.batch.core.JobExecution;
7
import org.springframework.batch.core.JobParameters;
8
import org.springframework.batch.core.JobParametersBuilder;
9
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
10
import org.springframework.batch.core.launch.JobLauncher;
11
import org.springframework.beans.factory.annotation.Autowired;
12
import org.springframework.boot.CommandLineRunner;
13
import org.springframework.boot.SpringApplication;
14
import org.springframework.boot.autoconfigure.SpringBootApplication;
15
17
18
public class WrittingMultipleDestinationsApplication implements CommandLineRunner{
19
20
private JobLauncher jobLauncher;
21
23
private Job job;
24
25
public static void main(String[] args) {
26
SpringApplication.run(WrittingMultipleDestinationsApplication.class, args);
27
}
28
30
public void run(String... args) throws Exception {
31
JobParameters jobParameters = new JobParametersBuilder()
32
.addString("JobId", String.valueOf(System.currentTimeMillis()))
33
.addDate("date", new Date())
34
.addLong("time",System.currentTimeMillis()).toJobParameters();
35
36
JobExecution execution = jobLauncher.run(job, jobParameters);
37
System.out.println("STATUS :: "+execution.getStatus());
38
}
39
}
Интерфейс, используемый для создания строки, представляющей объект.
Джава
xxxxxxxxxx
1
package com.example.aggregator;
2
import org.springframework.batch.item.file.transform.LineAggregator;
4
import com.example.model.Customer;
6
import com.fasterxml.jackson.databind.ObjectMapper;
7
public class CustomLineAggregator implements LineAggregator<Customer> {
9
private ObjectMapper objectMapper = new ObjectMapper();
10
11
12
public String aggregate(Customer item) {
13
try {
14
return objectMapper.writeValueAsString(item);
15
} catch (Exception e) {
16
throw new RuntimeException("Unable to serialize Customer", e);
17
}
18
}
19
}
JobConfiguration
Джава
xxxxxxxxxx
1
package com.example.configuration;
2
import java.io.File;
4
import java.util.ArrayList;
5
import java.util.HashMap;
6
import java.util.List;
7
import java.util.Map;
8
import javax.sql.DataSource;
10
import org.springframework.batch.core.Job;
12
import org.springframework.batch.core.Step;
13
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
14
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
15
import org.springframework.batch.item.ItemWriter;
16
import org.springframework.batch.item.database.JdbcPagingItemReader;
17
import org.springframework.batch.item.database.Order;
18
import org.springframework.batch.item.database.support.MySqlPagingQueryProvider;
19
import org.springframework.batch.item.file.FlatFileItemWriter;
20
import org.springframework.batch.item.support.CompositeItemWriter;
21
import org.springframework.batch.item.xml.StaxEventItemWriter;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.context.annotation.Bean;
24
import org.springframework.context.annotation.Configuration;
25
import org.springframework.core.io.FileSystemResource;
26
import org.springframework.oxm.xstream.XStreamMarshaller;
27
import com.example.aggregator.CustomLineAggregator;
29
import com.example.mapper.CustomerRowMapper;
30
import com.example.model.Customer;
31
34
public class JobConfiguration {
35
36
private JobBuilderFactory jobBuilderFactory;
37
38
39
private StepBuilderFactory stepBuilderFactory;
40
41
42
private DataSource dataSource;
43
44
45
public JdbcPagingItemReader<Customer> customerPagingItemReader(){
46
// reading database records using JDBC in a paging fashion
47
JdbcPagingItemReader<Customer> reader = new JdbcPagingItemReader<>();
48
reader.setDataSource(this.dataSource);
49
reader.setFetchSize(1000);
50
reader.setRowMapper(new CustomerRowMapper());
51
52
// Sort Keys
53
Map<String, Order> sortKeys = new HashMap<>();
54
sortKeys.put("id", Order.ASCENDING);
55
56
// MySQL implementation of a PagingQueryProvider using database specific features.
57
MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
58
queryProvider.setSelectClause("id, firstName, lastName, birthdate");
59
queryProvider.setFromClause("from customer");
60
queryProvider.setSortKeys(sortKeys);
61
62
reader.setQueryProvider(queryProvider);
63
64
return reader;
65
}
66
67
68
69
public FlatFileItemWriter<Customer> jsonItemWriter() throws Exception{
70
String customerOutputPath = File.createTempFile("customerOutput", ".out").getAbsolutePath();
71
System.out.println(">> Output Path = "+customerOutputPath);
72
73
FlatFileItemWriter<Customer> writer = new FlatFileItemWriter<>();
74
writer.setLineAggregator(new CustomLineAggregator());
75
writer.setResource(new FileSystemResource(customerOutputPath));
76
writer.afterPropertiesSet();
77
78
return writer;
79
}
80
81
82
public StaxEventItemWriter<Customer> xmlItemWriter() throws Exception{
83
String customerOutputPath = File.createTempFile("customerOutput", ".out").getAbsolutePath();
84
System.out.println(">> Output Path = "+customerOutputPath);
85
86
Map<String, Class> aliases = new HashMap<>();
87
aliases.put("customer", Customer.class);
88
89
XStreamMarshaller marshaller = new XStreamMarshaller();
90
marshaller.setAliases(aliases);
91
92
// StAX and Marshaller for serializing object to XML.
93
StaxEventItemWriter<Customer> writer = new StaxEventItemWriter<>();
94
writer.setRootTagName("customers");
95
writer.setMarshaller(marshaller);
96
writer.setResource(new FileSystemResource(customerOutputPath));
97
writer.afterPropertiesSet();
98
99
return writer;
100
}
101
102
103
104
public CompositeItemWriter<Customer> itemWriter() throws Exception{
105
List<ItemWriter<? super Customer>> writers = new ArrayList<>();
106
writers.add(xmlItemWriter());
107
writers.add(jsonItemWriter());
108
109
CompositeItemWriter<Customer> compositeItemWriter = new CompositeItemWriter<>();
110
compositeItemWriter.setDelegates(writers);
111
compositeItemWriter.afterPropertiesSet();
112
113
return compositeItemWriter;
114
}
115
116
117
118
public Step step1() throws Exception {
119
return stepBuilderFactory.get("step1")
120
.<Customer, Customer> chunk(10)
121
.reader(customerPagingItemReader())
122
.writer(itemWriter())
123
.build();
124
}
125
126
127
public Job job() throws Exception {
128
return jobBuilderFactory.get("job")
129
.start(step1())
130
.build();
131
}
132
}
Джава
xxxxxxxxxx
1
package com.example.mapper;
2
import java.sql.ResultSet;
4
import java.sql.SQLException;
5
import java.time.format.DateTimeFormatter;
6
import org.springframework.jdbc.core.RowMapper;
8
import com.example.model.Customer;
10
public class CustomerRowMapper implements RowMapper<Customer> {
12
private static final DateTimeFormatter DT_FORMAT = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
13
15
public Customer mapRow(ResultSet rs, int rowNum) throws SQLException {
16
return Customer.builder().id(rs.getLong("id"))
17
.firstName(rs.getString("firstName"))
18
.lastName(rs.getString("lastName"))
19
.birthdate(rs.getString("birthdate")).build();
20
}
21
}
Джава
xxxxxxxxxx
1
package com.example.model;
2
import lombok.AllArgsConstructor;
5
import lombok.Builder;
6
import lombok.Data;
7
import lombok.NoArgsConstructor;
8
10
11
12
13
public class Customer {
14
private Long id;
15
private String firstName;
16
private String lastName;
17
private String birthdate;
18
}
application.properties
Джава
xxxxxxxxxx
1
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
2
spring.datasource.url=jdbc:mysql://localhost:3306/test
3
spring.datasource.username=root
4
spring.datasource.password=root
5
spring.batch.initialize-schema=always
7
spring.batch.job.enabled=false
pom.xml
XML
xxxxxxxxxx
1
2
<project xmlns="http://maven.apache.org/POM/4.0.0"
3
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5
<modelVersion>4.0.0</modelVersion>
6
<parent>
7
<groupId>org.springframework.boot</groupId>
8
<artifactId>spring-boot-starter-parent</artifactId>
9
<version>2.2.2.RELEASE</version>
10
<relativePath ></relativePath> <!-- lookup parent from repository -->
11
</parent>
12
<groupId>com.example</groupId>
13
<artifactId>writtingMultipleDestinations</artifactId>
14
<version>0.0.1-SNAPSHOT</version>
15
<packaging>jar</packaging>
16
<name>writtingMultipleDestinations</name>
17
<description>Demo project for Spring Boot</description>
18
<properties>
20
<java.version>1.8</java.version>
21
</properties>
22
<dependencies>
24
<dependency>
25
<groupId>org.springframework.boot</groupId>
26
<artifactId>spring-boot-starter-batch</artifactId>
27
</dependency>
28
<dependency>
29
<groupId>org.springframework.boot</groupId>
30
<artifactId>spring-boot-starter-jdbc</artifactId>
31
</dependency>
32
<!-- Spring OXM -->
33
<dependency>
34
<groupId>org.springframework</groupId>
35
<artifactId>spring-oxm</artifactId>
36
</dependency>
37
<dependency>
38
<groupId>com.h2database</groupId>
39
<artifactId>h2</artifactId>
40
<scope>runtime</scope>
41
</dependency>
42
<dependency>
43
<groupId>mysql</groupId>
44
<artifactId>mysql-connector-java</artifactId>
45
<scope>runtime</scope>
46
</dependency>
47
<dependency>
48
<groupId>com.thoughtworks.xstream</groupId>
49
<artifactId>xstream</artifactId>
50
<version>1.4.7</version>
51
</dependency>
52
<dependency>
53
<groupId>org.projectlombok</groupId>
54
<artifactId>lombok</artifactId>
55
<version>1.18.2</version>
56
<optional>true</optional>
57
</dependency>
58
<dependency>
59
<groupId>org.springframework.boot</groupId>
60
<artifactId>spring-boot-starter-test</artifactId>
61
<scope>test</scope>
62
</dependency>
63
<dependency>
64
<groupId>org.springframework.batch</groupId>
65
<artifactId>spring-batch-test</artifactId>
66
<scope>test</scope>
67
</dependency>
68
</dependencies>
69
<build>
71
<plugins>
72
<plugin>
73
<groupId>org.springframework.boot</groupId>
74
<artifactId>spring-boot-maven-plugin</artifactId>
75
</plugin>
76
</plugins>
77
</build>
78
</project>
Вывод: созданы два файла ответов, и это означает, что мы можем записывать данные в несколько мест назначения.
Джава
xxxxxxxxxx
1
>> Output Path = C:\Users\user\AppData\Local\Temp\1\customerOutput5824034651210161854.out
2
>> Output Path = C:\Users\user\AppData\Local\Temp\1\customerOutput8870745056369564522.out
customerOutput8870745056369564522.out
Джава
xxxxxxxxxx
1
{"id":1,"firstName":"John","lastName":"Doe","birthdate":"10-10-1952 10:10:10"}
2
{"id":2,"firstName":"Amy","lastName":"Eugene","birthdate":"05-07-1985 17:10:00"}
3
{"id":3,"firstName":"Laverne","lastName":"Mann","birthdate":"11-12-1988 10:10:10"}
4
{"id":4,"firstName":"Janice","lastName":"Preston","birthdate":"19-02-1960 10:10:10"}
5
{"id":5,"firstName":"Pauline","lastName":"Rios","birthdate":"29-08-1977 10:10:10"}
6
{"id":6,"firstName":"Perry","lastName":"Burnside","birthdate":"10-03-1981 10:10:10"}
7
{"id":7,"firstName":"Todd","lastName":"Kinsey","birthdate":"14-12-1998 10:10:10"}
8
{"id":8,"firstName":"Jacqueline","lastName":"Hyde","birthdate":"20-03-1983 10:10:10"}
9
{"id":9,"firstName":"Rico","lastName":"Hale","birthdate":"10-10-2000 10:10:10"}
10
{"id":10,"firstName":"Samuel","lastName":"Lamm","birthdate":"11-11-1999 10:10:10"}
11
{"id":11,"firstName":"Robert","lastName":"Coster","birthdate":"10-10-1972 10:10:10"}
12
{"id":12,"firstName":"Tamara","lastName":"Soler","birthdate":"02-01-1978 10:10:10"}
13
{"id":13,"firstName":"Justin","lastName":"Kramer","birthdate":"19-11-1951 10:10:10"}
14
{"id":14,"firstName":"Andrea","lastName":"Law","birthdate":"14-10-1959 10:10:10"}
15
{"id":15,"firstName":"Laura","lastName":"Porter","birthdate":"12-12-2010 10:10:10"}
16
{"id":16,"firstName":"Michael","lastName":"Cantu","birthdate":"11-04-1999 10:10:10"}
17
{"id":17,"firstName":"Andrew","lastName":"Thomas","birthdate":"04-05-1967 10:10:10"}
18
{"id":18,"firstName":"Jose","lastName":"Hannah","birthdate":"16-09-1950 10:10:10"}
19
{"id":19,"firstName":"Valerie","lastName":"Hilbert","birthdate":"13-06-1966 10:10:10"}
20
{"id":20,"firstName":"Patrick","lastName":"Durham","birthdate":"12-10-1978 10:10:10"}
customerOutput5824034651210161854.out
XML
x
1
2
<customers>
3
<customer>
4
<id>1</id>
5
<firstName>John</firstName>
6
<lastName>Doe</lastName>
7
<birthdate>10-10-1952 10:10:10</birthdate>
8
</customer>
9
<customer>
10
<id>2</id>
11
<firstName>Amy</firstName>
12
<lastName>Eugene</lastName>
13
<birthdate>05-07-1985 17:10:00</birthdate>
14
</customer>
15
<customer>
16
<id>3</id>
17
<firstName>Laverne</firstName>
18
<lastName>Mann</lastName>
19
<birthdate>11-12-1988 10:10:10</birthdate>
20
</customer>
21
<customer>
22
<id>4</id>
23
<firstName>Janice</firstName>
24
<lastName>Preston</lastName>
25
<birthdate>19-02-1960 10:10:10</birthdate>
26
</customer>
27
<customer>
28
<id>5</id>
29
<firstName>Pauline</firstName>
30
<lastName>Rios</lastName>
31
<birthdate>29-08-1977 10:10:10</birthdate>
32
</customer>
33
<customer>
34
<id>6</id>
35
<firstName>Perry</firstName>
36
<lastName>Burnside</lastName>
37
<birthdate>10-03-1981 10:10:10</birthdate>
38
</customer>
39
<customer>
40
<id>7</id>
41
<firstName>Todd</firstName>
42
<lastName>Kinsey</lastName>
43
<birthdate>14-12-1998 10:10:10</birthdate>
44
</customer>
45
<customer>
46
<id>8</id>
47
<firstName>Jacqueline</firstName>
48
<lastName>Hyde</lastName>
49
<birthdate>20-03-1983 10:10:10</birthdate>
50
</customer>
51
<customer>
52
<id>9</id>
53
<firstName>Rico</firstName>
54
<lastName>Hale</lastName>
55
<birthdate>10-10-2000 10:10:10</birthdate>
56
</customer>
57
<customer>
58
<id>10</id>
59
<firstName>Samuel</firstName>
60
<lastName>Lamm</lastName>
61
<birthdate>11-11-1999 10:10:10</birthdate>
62
</customer>
63
<customer>
64
<id>11</id>
65
<firstName>Robert</firstName>
66
<lastName>Coster</lastName>
67
<birthdate>10-10-1972 10:10:10</birthdate>
68
</customer>
69
<customer>
70
<id>12</id>
71
<firstName>Tamara</firstName>
72
<lastName>Soler</lastName>
73
<birthdate>02-01-1978 10:10:10</birthdate>
74
</customer>
75
<customer>
76
<id>13</id>
77
<firstName>Justin</firstName>
78
<lastName>Kramer</lastName>
79
<birthdate>19-11-1951 10:10:10</birthdate>
80
</customer>
81
<customer>
82
<id>14</id>
83
<firstName>Andrea</firstName>
84
<lastName>Law</lastName>
85
<birthdate>14-10-1959 10:10:10</birthdate>
86
</customer>
87
<customer>
88
<id>15</id>
89
<firstName>Laura</firstName>
90
<lastName>Porter</lastName>
91
<birthdate>12-12-2010 10:10:10</birthdate>
92
</customer>
93
<customer>
94
<id>16</id>
95
<firstName>Michael</firstName>
96
<lastName>Cantu</lastName>
97
<birthdate>11-04-1999 10:10:10</birthdate>
98
</customer>
99
<customer>
100
<id>17</id>
101
<firstName>Andrew</firstName>
102
<lastName>Thomas</lastName>
103
<birthdate>04-05-1967 10:10:10</birthdate>
104
</customer>
105
<customer>
106
<id>18</id>
107
<firstName>Jose</firstName>
108
<lastName>Hannah</lastName>
109
<birthdate>16-09-1950 10:10:10</birthdate>
110
</customer>
111
<customer>
112
<id>19</id>
113
<firstName>Valerie</firstName>
114
<lastName>Hilbert</lastName>
115
<birthdate>13-06-1966 10:10:10</birthdate>
116
</customer>
117
<customer>
118
<id>20</id>
119
<firstName>Patrick</firstName>
120
<lastName>Durham</lastName>
121
<birthdate>12-10-1978 10:10:10</birthdate>
122
</customer>
123
</customers>
Дальнейшее чтение
Spring Batch: чтение XML-файла и запись в базу данных Oracle.
Пакетная обработка больших наборов данных с помощью Spring Boot и Spring Batch