Named Parameter 'vo' 활용

매핑 XML 파일에 정의되어 있는 쿼리문을 실행시키기 위해 필요한 입력 Parameter들을 Query 서비스에 전달할 때, 개별 Parameter들을 포함하고 있는 객체로 전달 가능하다. 따라서 입력 Parameter 개수나 이름이 변경되더라도, Query 서비스 사용 로직의 변경없이 매핑 XML 내의 해당되는 쿼리문만 변경함으로써 변경 사항 적용이 가능해지므로 쿼리문 변경이 용이해지는 장점을 제공한다.

Query 서비스 속성 정의 파일 Sample

다음은 Query 서비스를 정의한 applicationContext-query-common.xml 과 Query 서비스에서 읽어들일 매핑 XML 파일의 위치를 정의한 applicationContext-query-sqlloader.xml 파일의 일부이다.
<bean id="queryService" class="anyframe.core.query.impl.QueryServiceImpl">
	<property name="jdbcTemplate" ref="jdbcTemplate"/>
	<property name="sqlRepository" ref="sqlLoader"/>
	<!-- 중략 -->
</bean>
<bean id="jdbcTemplate" class="anyframe.core.query.impl.jdbc.PagingJdbcTemplate">
  <property name="dataSource" ref="common_datasource" />
</bean>  
<!-- 중략 -->

<bean name="sqlLoader" class="anyframe.core.query.impl.config.loader.SQLLoader">
   	<config:configuration>
 		    <filename>
 		      classpath:/services/query/mappings/mapping-namedparamvo-query.xml
 		    </filename>
 		    <!-- 중략 -->
	</config:configuration>		
</bean> 
<!-- 중략 -->

매핑 XML 파일 Sample

다음은 앞서 정의한 Query 서비스를 통해 로드된 mapping-namedparamvo-query.xml 로, Named Parameter로 전달된 'vo'를 활용한 다양한 쿼리문들을 포함하고 있다. Parameter명이 'vo'인 객체로부터 . 뒤에 붙은 이름에 대한 getter 메소드를 호출한 결과를 PreparedStatement에 셋팅한 후, 해당 쿼리문을 실행하게 된다.
<queryservice>
	<queries>
		<query id="insertCategory">
			<statement>
				INSERT INTO TBL_EXT_CATEGORY 
				(CATEGORY_NO, CATEGORY_NAME, CATEGORY_DESC, USE_YN, REG_ID, 
				  REG_DATE, MODIFY_ID, MODIFY_DATE) 
				VALUES (:vo.categoryNo, :vo.categoryName, :vo.categoryDesc, 
				  :vo.useYn, :vo.regId, sysdate, :vo.regId, sysdate)
			</statement>	
		</query>	
		<query id="updateCategory">
			<statement>
				UPDATE TBL_EXT_CATEGORY  
				SET CATEGORY_NAME = :vo.categoryName, 
				  CATEGORY_DESC = :vo.categoryDesc, 
				  USE_YN =:vo.useYn, MODIFY_ID = :vo.modifyId, 
				  MODIFY_DATE = sysdate
				WHERE CATEGORY_NO = :vo.categoryNo
			</statement>
		</query>	
		<query id="deleteCategory">
			<statement>
			delete from TBL_EXT_CATEGORY where CATEGORY_NO = :vo.categoryNo
			</statement>	
		</query>
		<query id="findCategoryList">
			<statement>
				SELECT CATEGORY_NO, CATEGORY_NAME, CATEGORY_DESC, USE_YN, REG_ID
				FROM TBL_EXT_CATEGORY
				WHERE CATEGORY_NO like :vo.categoryNo
			</statement>
			<result class="integration.anyframe.services.query.vo.CategoryVO"></result>
		</query>
		<query id="findCategory">
			<statement>
				SELECT CATEGORY_NO, CATEGORY_NAME, CATEGORY_DESC, USE_YN, REG_ID
				FROM TBL_EXT_CATEGORY
				WHERE CATEGORY_NO = :vo.categoryNo
			</statement>
			<result class="integration.anyframe.services.query.vo.CategoryVO"></result>
		</query>					
	</queries>
</queryservice>

Query 서비스 테스트 코드 Sample

다음은 앞서 언급한 매핑 XML 파일에 정의된 INSERT, SELECT, UPDATE, DELETE 쿼리문을 실행하는 소스 코드 QueryServiceTestNamedParamVO.java 이다. Query 서비스에 입력 Parameter 전달시 'vo'라는 Parameter명에 CategoryVO 또는 SearchVO 객체를 매핑시키고 있음을 알 수 있다.
/**
 * QueryService에 특정 쿼리의 입력 Parameter값을 전달할 때, named parameter 형태로 transfer
 * object를 전달한다. QueryService에서는 전달받은 객체의 getter 메소드를 호출하여 INSERT 쿼리문의
 * Parameter값을 셋팅하고 실행한다.
 */
public CategoryVO testInsertCategory() throws Exception {
	IQueryService queryService = (IQueryService) context
			.getBean("queryService");

	CategoryVO categoryVO = makeCategoryVO();

	Object[] args = new Object[] { "vo", categoryVO };
	int result = queryService.create("insertCategory",
			new Object[] { args });

	if (result != 1) {
		throw new Exception("Insert a new category failed");
	}

	return categoryVO;
}

/**
 * QueryService에 특정 쿼리의 입력 Parameter값을 전달할 때, named parameter 형태로 transfer
 * object를 전달한다. QueryService에서는 전달받은 객체의 getter 메소드를 호출하여 UPDATE 쿼리문의
 * Parameter값을 셋팅하고 실행한다.
 */
public void testUpdateCategory(CategoryVO categoryVO) throws Exception {
	IQueryService queryService = (IQueryService) context
			.getBean("queryService");
	categoryVO.setCategoryName("testUpdate");

	Object[] args = new Object[] { "vo", categoryVO };
	int result = queryService.update("updateCategory",
			new Object[] { args });

	if (result != 1) {
		throw new Exception("Update category failed");
	}
}

/**
 * QueryService에 특정 쿼리의 입력 Parameter값을 전달할 때, named parameter 형태로 transfer
 * object를 전달한다. QueryService에서는 전달받은 객체의 getter 메소드를 호출하여 DELETE 쿼리문의
 * Parameter값을 셋팅하고 실행한다.
 */
public void testDeleteCategory(CategoryVO categoryVO) throws Exception {
	IQueryService queryService = (IQueryService) context
			.getBean("queryService");

	Object[] args = new Object[] { "vo", categoryVO };
	int result = queryService.remove("deleteCategory",
			new Object[] { args });

	if (result != 1) {
		throw new Exception("Delete category failed");
	}

	args = new Object[] { "vo", categoryVO };
	Collection rtCollection = queryService.find("findCategory",
			new Object[] { args });

	if (rtCollection.size() != 0) {
		throw new Exception("Find categorylist failed");
	}
}

/**
 * QueryService에 특정 쿼리의 입력 Parameter값을 전달할 때, named parameter 형태로 transfer
 * object를 전달한다. QueryService에서는 전달받은 객체의 getter 메소드를 호출하여 SELECT 쿼리문의
 * Parameter값을 셋팅하고 실행한다.
 */
public void testFindCategory(String categoryNo, String categoryName)
		throws Exception {
	IQueryService queryService = (IQueryService) context
			.getBean("queryService");

	CategoryVO searchVO = new CategoryVO();
	searchVO.setCategoryNo(categoryNo);

	Object[] args = new Object[] { "vo", searchVO };
	Collection rtCollection = queryService.find("findCategory",
			new Object[] { args });

	if (rtCollection.size() != 1) {
		throw new Exception("Find category failed");
	}

	CategoryVO categoryVO = (CategoryVO) rtCollection.iterator().next();
	if (!(categoryNo.equals(categoryVO.getCategoryNo()) && categoryName
			.equals(categoryVO.getCategoryName()))) {
		throw new Exception("Find category failed");
	}
}
앞서 소개된 샘플 테스트 코드를 포함하여 Query 서비스 소개 페이지에서 제공하는 모든 샘플 테스트 코드는 HSQL DB를 기반으로 실행된다. ( 단, ※ CallableStatement, LOB의 경우는 Oracle 9i, 10g를 기반으로 함. )

Resources

  • 다운로드
  • 샘플 테스트 코드를 포함하고 있는 anyframe-querytest-src.zip 파일을 다운받은 후, 테스트 환경 설정 을 참조하여 위에서 제시한 예제 코드를 실행해 볼 수 있다.
    Name
    Download
    anyframe-querytest-src.zip
    Download