본문 바로가기

Java/Spring

마이바티스(MyBatis) 동적 쿼리 Java로 만들기.



스프링은 3.0 부터 Java Config를 지원하기 시작했고, 스프링 부트는 XML 설정 없이 동작 한다. (물론 여전히 XML 설정은 가능하다.)


마이바티스 또한, XML 설정 없이 Java 클래스만을 사용하여서, 동적 쿼리 생성이 가능하다.


스프링부트까지 사용하면 금상첨화다.



먼저, 회원 목록을 조회할 Controller를 작성하자.


화면에서, "/members" 요청이 들어오면, 회원 목록의 JSON 문자열을 반환하게 한다.



Controller 의 요청을 받을 Service 클래스도 아래와 같이 작성한다.



이제부터 시작이다.


Service 의 요청을 처리해 줄 Mapper 인터페이스를 만든다. (DAO로 혹은, Repository로 이름짓기도 한다.)


@Mapper
interface MemberMapper {
}



@Mapper 어노테이션은 해당 interface를 마이바티스 매퍼로 등록하겠다는 뜻이다.


이제 여기에 Service 에서 호출할 findMembers 메서드를 작성한다.


만약 동적 쿼리를 작성할 필요가 없다면, 아래와 같이 @Select 어노테이션을 사용할 수 있다.


@Mapper
interface MemberMapper {

    @Select("SELECT id, name FROM MEMBER")
    public List findMembers();
}



이걸로 끝이다.


이제 서버를 시작하고, "/members" 주소로 요청을 보내면, MemberList가 Return 된다. (당연히 데이터를 넣어줘야 한다.)



아무래도, 쿼리를 어노테이션의 속성 값으로 넣어주는것은 보기가 좋지 않다.


MemberSQL 클래스를 만들고, static String 으로 선언하기로 했다.


아래와 같은 MemberSQL을 만든다.


class MemberSQL {
    public static final String FIND_MEMBERS =
            '''
            SELECT id, name FROM MEMBER
            '''
}



그루비의 MultiLine String 을 활용하기 위해서, Groovy 클래스를 만들었다.


이제, MemberMapper 클래스의 코드가 MemberSQL 을 참조하도록 고친다.


@Mapper
@Repository
interface MemberMapper {

    @Select(MemberSQL.FIND_MEMBERS)
    public List findMembers()
}



이제 본격적으로 동적쿼리를 조립해 보자.


동적 쿼리를 만들기 위해서는 @Select 어노테이션 대신에 @SelectProvider 어노테이션을 사용한다.


아래와 같이 선언한다.



type에 동적 쿼리를 조립할 클래스를 넣어준다.


필자는 MemberSQL 에서 쿼리를 조립하기로 했다.


method는 조립된 쿼리를 리턴할 메서드를 설정한다.


메서드에 선언된 @Param 어노테이션은 @SelectProvider에 설정된 method에서 동일하게 사용할 파라메터를 설정한다.



이제, MemberSQL에 @SelectProvider 에서 설정한 findMembersByName 메서드를 선언하고, 아래와 같이 코드를 작성한다.



Groovy 클래스는 MultiLine String를 위해서 사용했으며, Java 클래스로 선언해도 전혀 상관이 없다.


MemberSQL의 findMemberByName에서는 Mapper에서 받은 name 파라메터를 그대로 사용한다. (@Param 어노테이션 설정으로 사용가능하다.)


메서드에서 동적 쿼리를 조립해서 String을 리턴한다.


Java 문법을 사용해서 로직에 맞춰서 조립한다. (이 부분이 가장 매력적이다. XML 설정에서는 MyBatis가 제공하는 문법에 따라서만 조립이 가능했지만, Java 문법을 사용해 얼마든지 조립이 가능하다.)


예제로 만든 쿼리지만, 우리가 현업에서 만나게 되는 쿼리는 이렇게 간단하지가 않다.


아마도 그래서 Groovy의 MultiLine String이 특히 더 필요하다.



이것 말고도, 마이바티스에서 제공 하는 SQL 클래스도 사용이 가능하다. (import org.apache.ibatis.jdbc.SQL)




아래 링크에서 더 자세한 statementBuilder 관련 사용법을 알아 볼 수 있다.


MyBatis StatementBuilder



샘플 프로젝트는 아래에서 참조 가능하다.


https://github.com/keumhwanmoon/spring-boot-mybatis-with-groovy.git