DynamicHibernateService 활용

Hibernate만을 사용하여 데이터 액세스 처리를 수행할 때 입력 조건에 따라 동적으로 변경되는 HQL문을 만들기 위해서는 해당되는 자바 코드 내에 HQL문을 만들기 위한 로직이 포함되어야 한다. 이로 인해 HQL문과 자바 코드가 뒤섞이게 되어, 변경 및 유지보수가 어려워질 수 있다. 따라서, Anyframe에서는 별도 XML에 동적으로 변경되는 HQL문을 정의하여 Hibernate을 이용하여 처리할 수 있도록 Hibernate와 Velocity를 연동한 DynamicHibernateService를 제공한다. DynamicHibernateService에 대한 구현체는 1가지이며, 다음은 각 구현체별 사용 방법이다.

DynamicHibernateService

DynamicHibernate Configuration

다음은 DynamicHibernateService를 사용하기 위해 필요한 설정 정보이다.
Property Name
Description
Required
Default Value
sessionFactory Hibernate Session을 이용하여 HQL을 처리하는데 사용될 SessionFactory Bean의 id
Y
N/A
fileNames Dynamic HQL이 정의된 파일 경로 또는 해당하는 디렉토리 정보
Y
N/A

다음은 위에서 열거한 속성 정보를 포함한 context-hibernate.xml 파일의 일부이다.
<bean id="dynamicHibernateService"
	class="anyframe.core.hibernate.impl.DynamicHibernateService">
  <property name="sessionFactory" ref="sessionFactory" />
  <property name="fileNames">
    <list>
     <value>classpath:anyframe/core/hibernate/spring/dynamic-hibernate.xml</value>
    </list>
  </property>
</bean>
	  			

Dynamic HQL 정의 파일

DynamicHibernateService 속성 정의 파일 내의 fileNames 값으로 정의한 Dynamic HQL 정의 파일은 다음과 같이 구성된다.
<dynamic-hibernate> 태그는 여러 개의 query 태그를 포함할 수 있다. <query> 태그는 Velocity Rule을 접목시켜 Dynamic HQL문을 정의하기 위한 용도이며, 해당 HQL의 식별을 위해 name이라는 속성을 가져야 한다. <query> 태그 내에서는 text 치환과 named parameter 형태를 통해 Dynamic HQL 설정을 지원한다. 다음과 같은 syntax를 사용하면 다양한 형태로 운영시 조건 값에 따라 동적으로 HQL을 변환할 수 있다.
  • :ParameterName
  • : Named Parameter 형태로 변수를 지정할 때 사용한다.
  • {{치환 문자열 키}}
  • : 키에 해당하는 문자열로 치환하여 Query를 수행한다.
  • #if ~ (#elseif) ~ #end
  • : 조건 분기
  • # foreach ~ #end
  • : Loop
  • $velocityCount
  • : foreach 구문내의 Loop index를 체크하고자 하는 부분에 정의한다.
다음은 Dynamic HQL을 포함하고 있는 dynamic-hibernate.xml 파일의 일부로, 입력 조건에 director 정보가 포함되어 있으면, director 정보에 대해 like 조건으로 검색하는 HQL이 생성되고, 그렇지 않을 경우에는 title 정보에 대해 like 조건으로 검색하는 HQL이 생성될 것이다. 이 외에도 sortColumn, sortDirection 정보도 입력 조건으로 전달받도록 정의되어 있음을 알 수 있다.
<dynamic-hibernate>
	<query name="findMovieListAll">
		FROM Movie movie
		WHERE 
			#if(${director})
				movie.director like :director
			#else
				movie.title	like :title
			#end
		ORDER BY {{sortColumn}} {{sortDirection}}
		
	</query>
</dynamic-hibernate>			
				

DynamicHibernateService 활용 예제

DynamicHibernateService를 활용하기 위해서는 MovieDAOHibernateImpl 코드에서처럼 DynamicHibernateService를 통해 입력 조건과 해당 Dynamic HQL의 name을 전달하도록 한다.
			
public List findMovieList(int conditionType, String condition)
		throws Exception {
	Object[] args = new Object[3];
	if (conditionType == 0) {
		args[0] = "director=%" + condition + "%";
		args[1] = "sortColumn=movie.director";
	} else {
		args[0] = "title=%" + condition + "%";
		args[1] = "sortColumn=movie.title";
	}
	args[2] = "sortDirection=ASC";

	return dynamicHibernateService.findList("findMovieListAll", args);
}				
				

Resources

  • 다운로드
  • 샘플 테스트 코드를 포함하고 있는 anyframe-hibernatetest-src.zip 파일을 다운받은 후, 테스트 환경 설정 을 참조하여 위에서 제시한 예제 코드 (src/test/java 폴더의 anyframe.core.hibernate.spring 패키지에 속한 HibernateDynamicQueryTest.java)를 실행해 볼 수 있다.
    Name
    Download
    anyframe-hibernatetest-src.zip
    Download