MyBatis 어노테이션에서 Groovy “”” 사용하기

기본

정상혁 님의 포스트에 이클립스에 Groovy를 세팅하는 자세한 방법이 나와있는데요. 따라하다 보니 몇 가지 문제가 발생했습니다.

  • Maven에서 빌드 시, testCompile 골에서 예외 발생.
  • slf4j 사용시, 로거를 초기화 할 수 없어 예외 발생.
  • Groovy 클래스를 실행 할 수 없음.

마지막 것은 제 삽질입니다 (…) 이번 포스팅은 위 세 가지 문제를 해결해 MyBatis 어노테이션에서 Groovy 삼중 큰따옴표를 쓰는 것이 목표입니다.

1. Maven에서 빌드 시, testCompile 골에서 예외 발생.

로그에는 심볼을 찾을 수 없다고 나오는데 사실 ClassNotFound 예외입니다. Maven으로 빌드 도중 JUnit 테스트를 할 때, groovy 파일을 먼저 컴파일 하지 않아 발생합니다.

GMaven 홈페이지의 Building Groovy Projects 글을 보면 <goal> 설정 부분에 stub 만드는 골이 있는 것을 볼 수 있습니다.

<goals>
	<goal>generateStubs</goal>
	<goal>compile</goal>
	<goal>generateTestStubs</goal>
	<goal>testCompile</goal>
</goals>

이 스텁 골들의 역할은 maven-compiler-plugin이 compile 골과 testCompile 골을 실행하기 전에 groovy 클래스들을 java 소스로 변환시켜 주는 것입니다. 그래서 maven-compiler-plugin이 문제 없이 자신의 골을 수행할 수 있도록 만들어 줍니다.

2. slf4j 사용시, 로거를 초기화 할 수 없어 예외 발생.

GMaven은 Maven 플러그인이고 실제로 Groovy 실행을 위해서는 gmaven runtime API가 필요합니다.

<dependency>
    <groupId>org.codehaus.gmaven.runtime</groupId>
    <artifactId>gmaven-runtime-1.7</artifactId>
    <version>1.3</version>
</dependency>

위에 1.7은 어떤 버전의 Groovy를 실행할 지에 대한 것이고 아래 1.3은 gmaven-runtime API 자체 버전입니다.

이 API는 다른 API들과 의존성을 가지고 있는데요. 그 중 하나가 gshell-io 입니다. gshell-io는 다시 slf4j와 구현체인 gossip에 의존성을 가지고 있기 때문에 gossip으로 개발 중이 아니라면 제대로 Logger를 초기화 하지 못하거나 중복된 클래스가 있어서 예외가 발생할 수 있습니다. 해결 방법은 gshell-io에서 gossip을 exclude 하면 됩니다.

<dependency>
	<groupId>org.sonatype.gshell</groupId>
	<artifactId>gshell-io</artifactId>
	<version>2.4</version>
	<exclusions>
		<exclusion>
			<groupId>org.sonatype.gossip</groupId>
			<artifactId>gossip</artifactId>
		</exclusion>
	</exclusions>
</dependency>

3. Groovy 클래스를 실행 할 수 없음.

Groovy 클래스로 만들어 놓고 컴파일은 했는데 실행이 안되는 문제입니다.

http://dist.springsource.org/release/GRECLIPSE/e3.7/

위 주소의 이클립스 플러그인을 설치 할 때, Groovy 1.8 compile features를 설치할 수 있는데요. (옵션입니다.) 이것을 설치하게 되면 기본 Groovy 컴파일러가 1.8 용으로 잡히게 됩니다. 즉, 1.8 버전용으로 컴파일 된다는 뜻이고, GMaven 런타임 API의 경우 1.7 버전 용이기 때문에 1.8 버전의 Groovy API가 없어서 발생하는 에러입니다.

옵션에서 Groovy compiler 버전을 1.7로 바꿀 수가 있는데 이렇게 해도 에러가 계속 나더라구요. 해결책이라고 하기도 뭣하지만 결국 Groovy 1.8 compiler features를 언인스톨 해서 해결했습니다 (…)

4. class 파일로 컴파일도 완료 됐는데 cannot be resolved type 에러 발생

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-compiler-plugin</artifactId>
	<version>2.3.2</version>
	<configuration>
		<source>1.7</source>
		<target>1.7</target>
		<encoding>${default.encoding}</encoding>
		<includes>
			<include>**/*.java</include>
			<include>**/*.groovy</include>
		</includes>
	</configuration>
</plugin>

이렇게 groovy 파일도 인클루드 시켜 버립니다.

MyBatis 어노테이션에서 Groovy “”” 사용하기

드디어 메인 주제네요. MyBatis 어노테이션에서는 constant가 아니면 안됩니다. 그래서 유틸 클래스를 사용할 수가 없습니다. 따라서 Mapper 인터페이스 자체를  groovy 파일로 만들어서 사용하면 됩니다.

public interface SqlMapper {

	@Select("""
		SELECT reservation.id id, client.id clientId, client.name, client.department, menu.title, menu.id menuId, menu.building, reservation.reserve_date reserveDate, reservation.type
		FROM reservation, client, menu
		WHERE menu.building = #{building}
		AND client.id = reservation.client_id
		AND menu.id = reservation.menu_id
	""")
	List<Reservation> getReservationList(Reservation reservation);
}

그냥 Java처럼 보이지만 사실 Groovy 클래스입니다.

[링크] Java에서 XML없이 SQL개발하기

기본

최근에 MyBatis 어노테이션을 사용해보니 간단한 쿼리는 괜찮은데 쿼리가 길어지면 한 줄에 다 써놓자니 너무 길고 +로 연결하자니 다른 툴 사용할 때, 여간 불편한게 아니더라구요.

Groovy에서 삼중 큰따옴표(“””) 를 지원 하는지도 몰랐었는데, “”” 이렇게 스트링을 시작하면 문자열을 리터럴 그대로 인식할 수 있다고 합니다.(각각의 라인은 \n으로 처리됩니다.) Groovy는 JVM위에서 돌아가는 언어고, Java 문법도 다 지원해주죠. 이클립스에서 플러그인만 하나 추가해 주면 사용하는데 불편함이 없으니 정상혁님의 글대로 쿼리 유틸 클래스를 Groovy로 만들어 주면 매우 편할 것 같다는 생각이 들었습니다 🙂