/* * Copyright 2006-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package egovframework.brte.sample.example.support; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.springframework.batch.core.partition.support.Partitioner; import org.springframework.batch.item.ExecutionContext; import org.springframework.jdbc.core.JdbcTemplate; /** * DB 파티션 처리를 위해 테이블의 범위를 자동으로 지정하여 각각의 파티션에 할당하는 클래스 Data 들이 * 균일하게 분산되어 있으면 최적의 상태로 작동됨 * * @author 배치실행개발팀 * @since 2012. 07.30 * @version 1.0 * @see * * <pre> * << 개정이력(Modification Information) >> * * 수정일 수정자 수정내용 * ------- -------- --------------------------- * 2012. 07.30 배치실행개발팀 최초 생성 * * </pre> */ public class EgovColumnRangePartitioner implements Partitioner { private JdbcTemplate jdbcTemplate; // table private String table; // column private String column; /** * Data 가 있는 SQL 테이블 이름 셋팅 */ public void setTable(String table) { this.table = table; } /** * 파티션을 위한 컬럼명 셋팅 */ public void setColumn(String column) { this.column = column; } /** * DB 연결을 위한 DataSource */ public void setDataSource(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); } /** * DB테이블을 파션하는 것은 컬럼안의 Data들이 "균일하게 분산" 되어 있다고 가정한다. ExecutionContext 값은 * <code>minValue</code> 와 <code>maxValue</code> 의 키를 갖으며, 이 키를 기준으로 각각의 * 파티션에서 고려해야할 값들의 범위가 정해진다. */ @SuppressWarnings("deprecation") @Override public Map<String, ExecutionContext> partition(int gridSize) { // 테이블의 특정컬럼의 가장 작은 값 int min = jdbcTemplate.queryForInt("SELECT MIN(" + column + ") from " + table); // 테이블의 특정컬럼의 가장 큰 값 int max = jdbcTemplate.queryForInt("SELECT MAX(" + column + ") from " + table); // 하나의 Execution에서 지정될 Data의 범위(크기) int targetSize = (max - min) / gridSize + 1; Map<String, ExecutionContext> result = new HashMap<String, ExecutionContext>(); int number = 0; int start = min; // targetSize 만큼 의 Data int end = start + targetSize - 1; // 파티션된 범위의 수만큼 ExecutionContext를 생성하고 minVlaue 와 maxValue를 셋팅 while (start <= max) { ExecutionContext value = new ExecutionContext(); result.put("partition" + number, value); if (end >= max) { end = max; } value.putInt("minValue", start); value.putInt("maxValue", end); start += targetSize; end += targetSize; number++; } return result; } }