Query Service - Pagination
Query 서비스를 통해 조회 유형의 쿼리문 실행 시 전체 결과를 조회하지 않고 해당 페이지에 속한 데이터만 조회할 수 있으므로, 효율적이고
성능에 유리하다. Query 서비스는 페이징 처리를 위해 별도의 로직이나 특정 DB에 종속적인 쿼리문을 요구하지 않는다.
다만 조회하고자 하는 페이지의 번호와 한 페이지에 보여지는 데이터의 개수만 입력 parameter로 전달하면 된다.
Query 서비스 속성 정의 파일 Sample
다음은 Query 서비스를 정의한
applicationContext-query-common.xml
과
Query 서비스에서 읽어들일 매핑 XML 파일의 위치를 정의한
applicationContext-query-sqlloader.xml
파일의 일부이다.
(* 조회 유형의 쿼리에 대해 페이징 처리를 수행하기 위해서는 해당 DB에 맞는 PagingSQLGenerator를 추가 셋팅해주어야 함에 유의하도록 한다.)
<bean id="queryService" class="anyframe.core.query.impl.QueryServiceImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
<property name="sqlRepository" ref="sqlLoader"/>
<property name="pagingSQLGenerator" ref="pagingSQLGenerator"/>
<!-- 중략 -->
</bean>
<bean id="jdbcTemplate" class="anyframe.core.query.impl.jdbc.PagingJdbcTemplate">
<property name="dataSource" ref="common_datasource" />
</bean>
<bean id="pagingSQLGenerator" class="anyframe.core.query.impl.jdbc.generator.OraclePagingSQLGenerator"/>
<!-- 중략 -->
<bean name="sqlLoader" class="anyframe.core.query.impl.config.loader.SQLLoader">
<config:configuration>
<filename>
classpath:/services/query/mappings/mapping-pagination-query.xml
</filename>
<!-- 중략 -->
</config:configuration>
</bean>
<!-- 중략 -->
매핑 XML 파일 Sample
다음은 앞서 정의한 Query 서비스를 통해 로드된
mapping-pagination-query.xml
로,
테이블 매핑 정보와 쿼리문을 포함하고 있다.
<query id="selectUsingPagination">
<statement>
SELECT NAME FROM TBL_CUSTOMER WHERE SSNO like ?
</statement>
<param type="VARCHAR" />
<result class="integration.anyframe.core.query.vo.CustomerVO"/>
</query>
Query 서비스 테스트 코드 Sample
다음은 앞서 언급한 매핑 XML 파일에 정의된 SELECT 쿼리문을 실행하는 소스 코드
QueryServiceTestPagination.java
로,
페이징 처리된 수행 결과를 얻어 내기 위한 테스트 로직을 포함하고 있다.
/**
* SELECT 수행 결과를 특정 페이지별로 조회하는 테스트 코드
* 이 메소드에서는 TBL_CUSTOMER 테이블에 여러 데이터가 입력되었을 때, 한 페이지에 표현하고자 하는 데이터의 개수(5)와
* 조회 페이지 페이지 번호(3)를 입력하여 특정 페이지에 속한 데이터만 조회해 본다.
*/
public void testSelectQuery() throws Exception {
IQueryService queryService = (IQueryService) context
.getBean("queryService");
/** findWithRowCount() : 매핑 XML 파일에 정의되어 있는 query id를 이용하여 SELECT를 실행한다.
* findWithRowCount()는 한번의 호출로 해당 SELECT로 얻을 수 있는 전체
* 데이터의 개수와 특정 페이지에 해당하는 결과값들을 얻어 올 수 있다.
*/
HashMap resultMap = queryService.findWithRowCount("selectUsingPagination",
new Object[] { "%1234%" }, 3, 5);
CustomerVO customerVO = new CustomerVO();
Map rsMap = new HashMap();
// 특정 페이지에 속한 결과값들 추출
List resultList = (List) resultMap.get(IQueryService.LIST);
for(int i = 0 ; i < resultList.size() ; i ++){
customerVO = (CustomerVO)resultList.get(i);
customerVO.getNm();
}
// 해당 SELECT로 얻어질 수 있는 전체 데이터의 개수 추출
int totalSize = ((Long) resultMap.get(IQueryService.COUNT)).intValue();
if (resultList.size() != 5 || totalSize != 15) {
throw new Exception("Select query failed");
}
}
다음은 Query 서비스에서 제공하는 페이징 처리 기능을 사용하기 위해서 알아두어야 할 사항들이다.
public Collection find...(..., int pageIndex, int pageSize);- 페이지 번호가 1보다 작으면 결과 데이터가 없다. (Anyframe Core 3.3.0 이후)
- 페이지 번호가 1보다 작으면 첫번째 페이지가 조회된다. (Anyframe Core 3.2.0 이전)
- 한 페이지에 보여줘야 하는 데이터의 개수는 0보다 커야 한다.
- 페이지 번호와 한 페이지에 보여줘야 하는 데이터의 개수를 사용하여 계산한 값이 전체 결과 데이터의 개수보다 크면 결과 데이터가 없다.(Anyframe Core 3.3.0 이후)
- 페이지 번호와 한 페이지에 보여줘야 하는 데이터의 개수를 사용하여 계산한 값이 전체 결과 데이터의 개수보다 크면 마지막 페이지가 조회된다. (Anyframe Core 3.2.0 이전)
- 한 페이지에 보여줘야 하는 데이터의 개수가 생략될 경우 매핑 XML 파일의 <result>에 별도로 정의해 주어야 한다.
<query id="selectUsingPagination" isDynamic="false">
<statement>
SELECT NAME FROM TBL_CUSTOMER WHERE SSNO like ?
</statement>
<param type="VARCHAR" />
<result length="10" class="integration.anyframe.services.query.vo.CustomerVO"/>
</query>
앞서 소개된 샘플 테스트 코드를 포함하여 Query 서비스 소개 페이지에서 제공하는 모든 샘플 테스트 코드는 HSQL DB를
기반으로 실행된다. ( 단, ※ CallableStatement, LOB의 경우는 Oracle 9i, 10g를 기반으로 함. )
Resources
다운로드
샘플 테스트 코드를 포함하고 있는 anyframe-querytest-src.zip 파일을 다운받은 후, 테스트 환경 설정
을 참조하여
위에서 제시한 예제 코드를 실행해 볼 수 있다.
| Name
|
Download
|
| anyframe-querytest-src.zip |
Download
|