-
[Spring Batch] ItemReader(2) - JPAJava/Spring Batch 2021. 5. 30. 20:24
JPA 또는 자바 퍼시스턴스 API는 ORM 영역에서 표준화된 접근법을 제공한다. JPA는 아이템을 조회하는 데 커서 기반 방법은 제공하지 않는다.
스프링 부트가 제공하는 대부분의 기능을 사용할 때 그러하듯, 실제로 스프링 부트를 사용해서 JPA를 구성하는 것은 매우 쉽다. JPA를 사용하는 예제에서 신경 써야 할 부분은 개발하는 ItemReader를 구성하는 것이다.
앞서 언급했듯 JPA는 커서 기법의 데이터베이스 접근을 지원하지 않지만 페이징 기법의 데이터베이스 접근은 지원한다. ItemReader로는 org.springframework.batch.item.database.JpaPagingItemRader를 사용하는데, 해당 리더에는 네 개의 의존성이 필요하다. 필요한 의존성은 ExecutionContext 내 엔트리의 접두어로 사용되는 이름, 스프링 부트가 제공하는 entityManager, 실행할 쿼리, 파라미터다. 이 예제에서는 쿼리에 파라미터가 포함돼 있으므로 파라미터 값도 주입해야 한다. 아래의 예제에는 JPA로 데이터베이스에 접근하는 customerItemRader의 구성이다.
... @Bean @StepScope public JpaPagingItemReader<Customer> customerItemReader( EntityManagerFactory entityManagerFactory, @Value("#{jobParameters['city']}") String city){ return new JpaPagingItemReadeerBuilder<Customer>() .name("customerItemReader") .entityManagerFactory(entityManagerFactory) .queryString("select c from Customer c where c.city = :city") .parameterValues(Collections.singletonMap("city", city)) .build(); } ...
현재까지 구성한 잡을 실행하면 명령행에 지정한 도시에 속한 모든 고객의 이름과 주소가 출력된다. JPA는 쿼리를 지정하는 다른 방법도 제공한다. 바로 Query 객체를 사용하는 방법이다. JPA는 쿼리를 지정하는 다른 방법도 제공한다. 바로 Query 객체를 사용하는 방법이다. JPA가 제공하는 Query API를 사용하려면 org.springframework.batch.item.database.orm.JpaQueryProvider 인터페이스를 구현해야 한다. createQuery 메서드와 setEntityManager 메서드로 구성된 JpaQueryProvider 인터페이스는 JpaPagingItemReader가 실행에 필요한 Query를 가져오는데 사용된다. JpaQueryProvider 인터페이스를 쉽게 구현할 수 있도록 스프링 배치는 상속해서 사용할 수 있는 org.springframework.batch.item.database.orm.AbstractJpaQueryProvider 추상 기본 클래스를 제공한다. 아래의 예제는 위의 예제에 구성된 것과 동일한 쿼리를 반환하는 구현체다.
... public class CustomerByCityQueryProvider extends AbstractJpaQueryProvider{ private String cityName; public Query createQuery(){ EntityManager manager = getEntityManager(); Query query = manager.createQuery("select c from Customer " + "c where c.city = :city"); query.setParameter("city", cityName); return query; } public void afterPropertiesSet() throws Exception{ Assert.notNull(cityName, "city name is required"); } pubilic void setCityName(String cityName){ this.cityName = cityName; } } ...
CustomerByCItyQueryProvider에서는 AbstractJpaQueryProvider 기본 클래스를 사용해서 필요한 EntityManager를 가져오는 부분을 처리했다. 그리고는 JPA 쿼리를 생성하고 쿼리에 필요한 EntityManager를 가져오는 부분을 처리했다. 그리고는 JPA 쿼리를 생성하고 쿼리에 필요한 파라미터를 지정한 뒤 스프링 배치가 실행할 수 있도록 쿼ㅣ를 반환했다. 개발하는 ItemReader가 앞 예제에서 지정한 쿼리 문자열 대신 CustomerByCityQueryProvider를 사용하게 구성하려면 아래 예제에 나타난 것 처럼 단순히 queryString 파라미터를 queryProvider로 대체하며 된다.
... @Bean @StepScope public JpaPagingItemReader<Customer> customerItemReader( EntityManagerFactory entityManagerFactory, @Value("#{jobParameters['city']}") String city){ CustomerByCityQueryProvider queryProvider = new CustsomerByCityQueryProvider(); return new JpaPagingItemReadeerBuilder<Customer>() .name("customerItemReader") .entityManagerFactory(entityManagerFactory) .queryString(queryProvider) .parameterValues(Collections.singletonMap("city", city)) .build(); } ...
전체 소스
AcornPublishing/definitive-spring-batch
스프링 배치 완벽 가이드 2/e. Contribute to AcornPublishing/definitive-spring-batch development by creating an account on GitHub.
github.com
스프링 배치 완벽 가이드, 마이클 미넬라
'Java > Spring Batch' 카테고리의 다른 글
[Spring Batch] ItemReader(4) - 기존서비스 (0) 2021.06.13 [Spring Batch] ItemReader(3) - 저장프로시저(SP, Stored Procedure) (0) 2021.05.31 [Spring Batch] ItemReader(1) - JDBC (0) 2021.05.30 [Spring Batch] Step (0) 2021.05.15 [Spring Batch] 스프링 배치란 / 이용하면 좋은 이유 (0) 2021.05.10