-
13. ItemReader (XML)BackEnd/Spring Batch 2021. 12. 30. 22:10반응형
JAVA XML API로는 DOM 방식, SAX 방식, Stax 방식(Streaming API for XML)이 있습니다.
DOM 방식
문서 전체를 메모리에 로드한 후 Tree 형태로 만들어서 데이터를 처리하는 방식(pull 방식)으로 엘리먼트 제어는 유연하나 문서 크기가 클 경우 메모리 사용이 많고 속도가 느립니다.
SAX 방식
문서의 항목을 읽을 때 마다 이벤트가 발생하여 데이터를 처리하는 방식(push 방식)으로 메모리 비용이 적고 속도가 빠른 장점은 있으나 엘리멘트 제어가 어렵습니다.
StAX 방식
DOM과 SAX의 장점과 단점을 보완한 API 모델로서 push와 pull을 동시에 제공합니다. XML 문서를 읽고 쓸 수 있는 양방향 파서기를 지원하며, XML 파일의 항목에서 항목으로 직접 이동하면서 Stax 파서기를 통해 구문을 분석합니다.
- Iterator API 방식: XMLEventReader의 nextEvent()를 호출해서 이벤트 객체를 가지고 오며, 이벤트 객체는 XML 태그 유형(요소, 텍스트, 주석 등)에 대한 정보를 제공함
- Cursor API 방식: JDBC Resultset처럼 작동하는 API로서 XMLStreamReader는 XML 문서의 다음 요소로 커서를 이동합니다. 커서에서 직접 메서드를 호출하여 현재 이벤트에 대한 자세한 정보를 얻습니다.
스프링 배치는 특정한 XML 바인딩 기술을 강요하지 않고 Spring OXM(Object XML Mapping)에 위임합니다. 바인딩 기술을 제공하는 구현체를 선택해서 처리하도록 합니다. StAX 방식으로 XML 문서를 처리하는 StaxEventItemReader를 제공하며, XML을 읽어 자바 객체로 매핑하고 자바 객체를 XML로 쓸 수 있는 트랙잭션 구조를 지원합니다.
Spring-OXM
- Marshaller: marshall - 객체를 XML로 직렬화하는 행위
- Unmarshaller: unmarshall - XML을 객체로 역직렬화하는 행위
- Marshalle와 Unmarshaller 바인딩 기능을 제공하는 오픈소스로 JaxB2, Castor, XmlBeans, Xstream 등이 있습니다.
StaxEventItemReader
Stax API 방식으로 데이터를 읽어들이는 ItemReader입니다. Spring-OXM과 Xstream 의존성을 추가해야 합니다.
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>5.3.7</version> </dependency> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.16</version> </dependency>
API
package io.springbatch.springbatchlecture; import lombok.RequiredArgsConstructor; import org.springframework.batch.core.*; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.xml.StaxEventItemReader; import org.springframework.batch.item.xml.builder.StaxEventItemReaderBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.oxm.xstream.XStreamMarshaller; import java.util.Date; import java.util.HashMap; import java.util.Map; @RequiredArgsConstructor @Configuration public class XMLConfiguration { private final JobBuilderFactory jobBuilderFactory; private final StepBuilderFactory stepBuilderFactory; @Bean public Job job() { return jobBuilderFactory.get("batchJob") .incrementer(new RunIdIncrementer()) .start(step1()) .build(); } @Bean public Step step1() { return stepBuilderFactory.get("step1") .<Customer, Customer>chunk(3) .reader(customItemReader()) .writer(customItemWriter()) .build(); } @Bean public StaxEventItemReader<Customer> customItemReader() { return new StaxEventItemReaderBuilder<Customer>() .name("xmlFileItemReader") // 읽을 파일을 나타내는 스프링 Resource .resource(new ClassPathResource("customer.xml")) // 객체에 매핑되는 조각을 감싸고 있는 루트 엘리먼트 이름 .addFragmentRootElements("customer") // Spring OXM이 지원하는 XML의 조각을 객체에 매핑시키는 Unmarshaller .unmarshaller(itemMarshaller()) .build(); } @Bean public ItemWriter<Customer> customItemWriter() { return items -> { for (Customer item : items) { System.out.println(item.toString()); } }; } @Bean public XStreamMarshaller itemMarshaller() { // 맵으로 alias 지정 Map<String, Class<?>> aliases = new HashMap<>(); // 첫번째 키는 조각의 루트 엘리먼트, 값은 바인딩할 객체 타입 aliases.put("customer", Customer.class); // 두번째 부터는 하위 엘리먼트와 각 클래스 타입 aliases.put("id", Long.class); aliases.put("name", String.class); aliases.put("age", Integer.class); XStreamMarshaller xStreamMarshaller = new XStreamMarshaller(); xStreamMarshaller.setAliases(aliases); return xStreamMarshaller; } }
customer.xml
<?xml version="1.0" encoding="UTF-8" ?> <customers> <customer id="1"> <id>1</id> <name>hong gil dong1</name> <age>40</age> </customer> <customer> <id>2</id> <name>hong gil dong2</name> <age>42</age> </customer> <customer> <id>3</id> <name>hong gil dong3</name> <age>43</age> </customer> </customers>
[참고자료]
반응형'BackEnd > Spring Batch' 카테고리의 다른 글
15. ItemReader (DB) (0) 2021.12.31 14. ItemReader (Json) (0) 2021.12.30 12. ItemReader (File) (0) 2021.12.30 11. 스프링 배치 청크 프로세스 (Chunk) (0) 2021.12.24 10. Scope (0) 2021.12.24