자바 API

이제 MyBatis 를 설정하는 방법과 매핑을 만드는 방법을 알게 되었다. 이미 충분히 잘 사용할 준비가 된 셈이다. MyBatis 자바 API 는 당신의 노력에 대한 보상을 얻게 할 것이다. JDBC 와 비교해보면, MyBatis 는 코드를 굉장히 단순하게 만들고 깔끔하게 만든다. 이해하기 쉬워서 유지보수도 편하게 해준다. MyBatis 3 은 SQL Map 을 사용하는 많은 수의 개선 내용을 소개했다.

디렉터리 구조

자바 API 를 살펴보기 전에, 디렉터리 구조에 대해 전반적으로 이해하는 것이 중요하다. MyBatis 는 매우 유연하고 파일을 사용해서 어떤 것도 할 수 있다. 하지만 프레임워크이기 때문에 선호하는 방법이 있다.

전형적인 애플리케이션 디렉터리 구조를 살펴보자.

/my_application
  /bin
  /devlib
  /lib                <-- MyBatis *.jar 파일이 여기 있다.
  /src
    /org/myapp/
      /action
      /data           <-- MyBatis 산출물이 여기 있다. Mapper 클래스, XML 설정, XML 매핑 파일들
        /mybatis-config.xml
        /BlogMapper.java
        /BlogMapper.xml
      /model
      /service
      /view
    /properties       <-- XML 설정파일에 포함된 프로퍼티들이 여기 있다.
  /test
    /org/myapp/
      /action
      /data
      /model
      /service
      /view
    /properties
  /web
    /WEB-INF
      /web.xml

이건 선호되는 형태이지 반드시 따라야 하는 요구사항이 아님을 기억해두라. 하지만 이러한 공통적인 형태를 사용하면 많은 사람들이 쉽게 이해할 것이다.

이 섹션의 나머지 예제는 디렉터리 구조가 이렇게 되어 있다고 가정하고 설명한다.

SqlSessions

MyBatis 를 사용하기 위한 기본적인 자바 인터페이스는 SqlSession 이다. 이 인터페이스를 통해 명령어를 실행하고, 매퍼를 얻으며 트랜잭션을 관리 할 수 있다. 우리는 SqlSession 에 대해서 좀더 얘기해볼 것이지만 먼저 SqlSession 의 인스턴스를 만드는 방법을 배워보자. SqlSession 은 SqlSessionFactory 인스턴스를 사용해서 만든다. SqlSessionFactory 는 몇가지 방법으로 SqlSession 인스턴스를 생성하기 위한 메서드를 포함하고 있다. SqlSessionFactory 자체는 XML, 애노테이션 또는 자바 설정에서 SqlSessonFactory 를 생성할 수 있는 SqlSessionFactoryBuilder 를 통해 만들어진다.

참고 Spring이나 Guide와 같은 의존성 삽입 프레임워크와 함께 사용할때, SqlSessions은 DI프레임워크에 의해 생성되고 삽입된다. 그래서 SqlSessionFactoryBuilder 나 SqlSessionFactory가 필요하지 않을 것이기 때문에 SqlSession 섹션으로 바로 넘어가도 무방하다. 추가적인 정보는 MyBatis-Spring이나 MyBatis-Guice를 참고하길 바란다.

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder 는 5 개의 build() 메서드를 가진다. 각각은 서로 다른 소스에서 SqlSession 을 빌드한다.

SqlSessionFactory build(InputStream inputStream)
SqlSessionFactory build(InputStream inputStream, String environment)
SqlSessionFactory build(InputStream inputStream, Properties properties)
SqlSessionFactory build(InputStream inputStream, String env, Properties props)
SqlSessionFactory build(Configuration config)

처음 4 개의 메서드가 가장 공통적이다. XML 문서를 나타내는 Reader 인스턴스를 가진다. SqlMapConfig.xml 파일은 위에서 다루었다. 선택적으로 사용가능한 프로퍼티는 environment 와 properties 이다. environment 는 데이터소스와 트랜잭션 관리자를 포함하여 로드할 환경을 판단한다. 예를 들면:

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
        ...
    <dataSource type="POOLED">
        ...
  </environment>
  <environment id="production">
    <transactionManager type="MANAGED">
        ...
    <dataSource type="JNDI">
        ...
  </environment>
</environments>

environment 파라미터를 가진 메서드를 호출한다면, MyBatis 는 사용할 환경을 위한 설정을 사용할 것이다. 물론 잘못된 환경설정을 사용하면, 에러를 보게 될 것이다. environment 파라미터를 가지지 않는 메서드 중 하나를 호출한다면, 디폴트 환경(위 예제에서 default=“development”)이 사용될 것이다.

properties 인스턴스를 가진 메서드를 호출하면, MyBatis 는 프로퍼티들을 로드해서 설정에서 사용가능한 부분을 사용할 것이다. 프로퍼티들은 ${propName} 와 같은 문법을 사용해서 설정의 값으로 대체될 수 있다.

프로퍼티들은 SqlMapConfig.xml 파일에서 사용되거나 직접 명시할 수 있다. 그러므로 프로퍼티들의 우선순위를 이해하는 것이 중요하다. 우리는 앞서 언급하긴 했지만, 쉽게 이해할 수 있도록 다시 보여주도록 하겠다.


프로퍼티가 한개 이상 존재한다면, MyBatis 는 일정한 순서로 로드한다.:

  • properties 요소에 명시된 속성을 가장 먼저 읽는다.
  • properties 요소의 클래스패스 자원이나 url 속성으로 부터 로드된 속성을 두번재로 읽는다. 그래서 이미 읽은 값이 있다면 덮어쓴다.,
  • 마지막으로 메서드 파라미터로 전달된 속성을 읽는다. 앞서 로드된 값을 덮어쓴다

그래서 가장 우선순위가 높은 속성은 메서드의 파라미터로 전달된 값이고 그 다음은 자원및 url 속성이고 마지막은 properties 요소에 명시된 값이다.


요약해보면, 처음 4 개의 메서드는 사실 같지만, environment 그리고/또는 properties 에 명시한 값을 오버라이드한다. mybatis-config.xml 파일에서 SqlSessionFactory 를 빌드하는 예제이다.

String resource = "org/mybatis/builder/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);

Resources 유틸리티 클래스를 사용하고 있는 것을 주의깊게 보면 된다. 이 클래스는 org.apache.ibatis.io 패키지에 있다. Resources 클래스는 그 이름이 나타내는 것처럼, 클래스패스나 파일 시스템 또는 웹 URL 에서 자원으로 로드하도록 해준다. IDE 를 통해 클래스의 소스 코드를 보는 것으로 유용한 메서드를 보게 될 것이다. 그 유용한 메서드 목록들이다.

URL getResourceURL(String resource)
URL getResourceURL(ClassLoader loader, String resource)
InputStream getResourceAsStream(String resource)
InputStream getResourceAsStream(ClassLoader loader, String resource)
Properties getResourceAsProperties(String resource)
Properties getResourceAsProperties(ClassLoader loader, String resource)
Reader getResourceAsReader(String resource)
Reader getResourceAsReader(ClassLoader loader, String resource)
File getResourceAsFile(String resource)
File getResourceAsFile(ClassLoader loader, String resource)
InputStream getUrlAsStream(String urlString)
Reader getUrlAsReader(String urlString)
Properties getUrlAsProperties(String urlString)
Class classForName(String className)

마지막 build 메서드는 Configuration 의 인스턴스를 가진다. Configuration 클래스는 SqlSessionFactory 인스턴스에 대해 알 필요가 있는 모든 것으로 가지고 있다. Configuration 클래스는 SQL Map 을 찾거나 관리하는 것을 포함하여 설정을 살펴보기 위해 유용하다. Configuration 클래스는 앞서 봤던 모든 설정을 처리할 수 있으며, 자바 API 로 나타낼 수 있다. SqlSessionFactory 를 생성하기 위해 Configuration 인스턴스를 build() 메서드에 전달하는 예제이다.

DataSource dataSource = BaseDataTest.createBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();

Environment environment = new Environment("development", transactionFactory, dataSource);

Configuration configuration = new Configuration(environment);
configuration.setLazyLoadingEnabled(true);
configuration.setEnhancementEnabled(true);
configuration.getTypeAliasRegistry().registerAlias(Blog.class);
configuration.getTypeAliasRegistry().registerAlias(Post.class);
configuration.getTypeAliasRegistry().registerAlias(Author.class);
configuration.addMapper(BoundBlogMapper.class);
configuration.addMapper(BoundAuthorMapper.class);

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(configuration);

이제 SqlSessionFactory 를 만들었다. SqlSession 인스턴스를 만들기 위해 사용해보자.

SqlSessionFactory

SqlSessionFactory 는 SqlSession 인스턴스를 생성하기 위해 사용할 수 있는 6 개의 메서드를 가지고 있다. 6 개의 메서드가 선택해서 사용하는 것들을 보자.

  • Transaction: 세션에서 트랜잭션 스코프 또는 자동 커밋을 사용하고 싶은가?
  • Connection: 설정된 DataSource 에서 Connection 을 회득하고 싶은가?
  • Execution: PreparedStatements 그리고/또는 배치(insert, delete 를 포함해서) 업데이트를 재사용하고 싶은가?

오버로드된 메서드인 penSession() 이 3 가지를 적절히 혼합해서 사용할 수 있다.

SqlSession openSession()
SqlSession openSession(boolean autoCommit)
SqlSession openSession(Connection connection)
SqlSession openSession(TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType,TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType)
SqlSession openSession(ExecutorType execType, boolean autoCommit)
SqlSession openSession(ExecutorType execType, Connection connection)
Configuration getConfiguration();

파라미터를 가지지 않는 디폴트 openSession() 메서드는 다음과 같은 성격을 가진 SqlSession 을 만들것이다.

  • 트랜잭션 스코프는 시작될 것이다.
  • Connection 객체는 활성화된 환경에 의해 설정된 DataSource 인스턴스를 획득할 것이다.
  • 트랜잭션 격리 레벨은 드라이버나 데이터소스가 디폴트로 제공하는 옵션을 사용할 것이다.
  • PreparedStatements 는 재사용되지 않을 것이다. 그리고 update 또한 배치처리되지 않을 것이다.

메서드 대부분은 그 이름과 파라미터가 그 역할을 충분히 설명한다. 자동커밋을 활성화하기 위해서, autoCommit 파라미터에 “true” 값을 셋팅하라. 자체적인 커넥션을 제공하기 위해서는, connection 파라미터에 Connection 인스턴스를 셋팅하라.

Connection 과 autoCommit 둘다 셋팅하는 것을 오버라이드하지 않는다. 왜냐하면 MyBatis 는 제공된 connection 객체를 셋팅할때마다 현재 사용중인 것을 사용한다. MyBatis 는 TransactionIsolationLevel 라고 불리는 트랜잭션 격리 레벨을 위한 자바 enum 래퍼를 사용한다. JDBC 를 5 가지를 지원한다(NONE, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE).

새롭게 보일수 있는 하나의 파라미터는 ExecutorType 이다. enum 으로는 3 개의 값을 정의한다.

  • ExecutorType.SIMPLE: 이 타입의 실행자는 아무것도 하지 않는다. 구문 실행마다 새로운 PreparedStatement 를 생성한다.
  • ExecutorType.REUSE: 이 타입의 실행자는 PreparedStatements 를 재사용할 것이다.
  • ExecutorType.BATCH: 이 실행자는 모든 update 구문을 배치처리하고 중간에 select 가 실행될 경우 필요하다면 경계를 표시한다. 이러한 과정은 행위를 좀더 이해하기 쉽게 하기 위함이다.

참고 SqlSessionFactory 에서 언급하지 않는 한개 이상의 메서드가 있다. getConfiguration() 메서드인데, 이 메서드는런타임시 MyBatis 설정을 조사하는 Configuration 인스턴스를 리턴할것이다.

참고 MyBatis 이전저번을 사용했다면, 세션, 트랜잭션 그리고 배치들을 여기저기서 찾게 될 것이다. 이것들은 더이상 사용되지 않는다. 세가지 모두 세션의 범위에 모두 포함되었다. 이것들이 제공하던 모든 기능을 사용하기 위해 각각이 필요한 것 아니다.

SqlSession

앞서 언급한 것처럼, SqlSession 인스턴스는 MyBatis 에서 굉장히 강력한 클래스이다. 구문을 실행하고, 트랜잭션을 커밋하거나 롤백하는 그리고 mapper 인스턴스를 습득하기 위해 필요한 모든 메서드를 찾을 수 있을 것이다.

SqlSession 에는 20 개 이상의 메서드가 있다. 좀더 적절히 모아서 보도록 하자.

구문을 실행하는 메서드

이 메서드들은 SQL 매핑 XML 파일에 정의된 SELECT, INSERT, UPDATE 그리고 DELETE 구문을 실행하기 위해 사용된다. 메서드 이름 자체가 그 역할을 설명하도록 명명되었다. 메서드 각각은 구문의 ID 와 파라미터 객체(원시타입, 자바빈, POJO 또는 Map)을 가진다.

<T> T selectOne(String statement, Object parameter)
<E> List<E> selectList(String statement, Object parameter)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey)
int insert(String statement, Object parameter)
int update(String statement, Object parameter)
int delete(String statement, Object parameter)

selectOne 과 selectList 의 차이점은 selectOne 메서드는 오직 하나의 객체만을 리턴해야 한다는 것이다. 한개 이상을 리턴하거나 null 이 리턴된다면, exception 이 발생할 것이다. 얼마나 많은 객체가 리턴될지 모른다면, selectList 를 사용하라. 객체의 존재여부를 체크하고 싶다면, 개수를 리턴하는 방법이 더 좋다. selectMap 은 결과 목록을 Map 을 변환하기 위해 디자인된 특별한 경우이다. 이 경우 결과 객체의 프로퍼티 중 하나를 키로 사용하게 된다. 모든 구문이 파라미터를 필요로 하지는 않기 때문에, 파라미터 객체를 요구하지 않는 형태로 오버로드되었다.

insert, update 그리고 delete 메서드에 의해 리턴되는 값은 실행된 구문에 의해 영향을 받은 레코드수를 표시한다.

<T> T selectOne(String statement)
<E> List<E> selectList(String statement)
<K,V> Map<K,V> selectMap(String statement, String mapKey)
int insert(String statement)
int update(String statement)
int delete(String statement)

마지막으로, 리턴되는 데이터의 범위를 제한하거나 결과를 핸들링 하는 로직을 부여할 수 있는 3 개의 select 메서드가 있다.

<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
void select (String statement, Object parameter, ResultHandler<T> handler)
void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler<T> handler)

RowBounds 파라미터는 MyBatis 로 하여금 특정 개수 만큼의 레코드를 건너띄게 한다. RowBounds 클래스는 offset 과 limit 둘다 가지는 생성자가 있다.

int offset = 100;
int limit = 25;
RowBounds rowBounds = new RowBounds(offset, limit);

가장 좋은 성능을 위해, 결과셋의 타입을 SCROLL_SENSITIVE 나 SCROLL_INSENSITIVE 로 사용하라.

ResultHandler 파라미터는 레코드별로 다룰수 있도록 해준다. List 에 추가할수도 있고, Map, Set 을 만들수도 있으며, 각각의 결과를 그냥 던질수도 있다. ResultHandler 로 많은 것을 할 수 있고 MyBatis 는 결과셋을 다루기 위해 내부적으로 사용한다.

인터페이스는 매우 간단하다.

package org.apache.ibatis.session;
public interface ResultHandler<T> {
  void handleResult(ResultContext<? extends T> context);
}

ResultContext 파라미터는 결과 객체에 접근할 수 있도록 해준다.

트랙잭션 제어 메서드

트랜잭션을 제어하기 위해 4 개의 메서드가 있다. 물론 자동커밋을 선택하였거나 외부 트랜잭션 관리자를 사용하면 영향이 없다. 어쨌든, Connection 인스턴스에 의해 관리되고 JDBC 트랜잭션 관리자를 사용하면, 이 4 개의 메서드를 사용할 수 있다.

void commit()
void commit(boolean force)
void rollback()
void rollback(boolean force)

기본적으로 MyBatis 는 insert, update 또는 delete 를 호출하여 데이터베이스가 변경된 것으로 감지하지 않는 한 실제로 커밋하지 않는다. 이러한 메서드 호출없이 변경되면, 커밋된 것으로 보장하기 위해 commit 와 rollback 메서드에 true 값을 전달한다.

참고 MyBatis-Spring 과 MyBatis-Guice는 선언적인 트랜잭션 관리기법을 제공한다. 그래서 Spring이나 Guice와 함께 MyBatis를 사용한다면, 해당되는 메뉴얼을 꼭 참고하길 바란다.

세션 레벨의 캐시를 지우기
void clearCache()

SqlSession 인스턴스는 update, commit, rollback 또는 close 할때마다 지워지는 로컬 캐시이다. 명시적으로 닫기 위해서는, clearCache()메서드를 호출할 수 있다.

SqlSession 을 반드시 닫도록 한다.
void close()

반드시 기억해야 하는 중요한 것은 당신이 열었던 세션을 닫아주는 것이다. 확실히 하기 위해 가장 좋은 방법은 다음과 같은 형태로 개발하는 것이다.

SqlSession session = sqlSessionFactory.openSession();
try {
    // following 3 lines pseudocod for "doing some work"
    session.insert(...);
    session.update(...);
    session.delete(...);
    session.commit();
} finally {
    session.close();
}

JDK 1.7이상과 마이바티스 3.2이상을 사용한다면 다음처럼 try-with-resources 구문을 사용할 수 있다.

try (SqlSession session = sqlSessionFactory.openSession()) {
    // following 3 lines pseudocode for "doing some work"
    session.insert(...);
    session.update(...);
    session.delete(...);
    session.commit();
}

참고 SqlSessionFactory 처럼, SqlSession 이 getConfiguration() 메서드를 호출하여 Configuration 인스턴스를 얻을 수 있다.

Configuration getConfiguration()
Mappers 사용하기
<T> T getMapper(Class<T> type)

다양한 insert, update, delete 그리고 select 메서드는 강력하지만, 다소 장황하고 타입에 안전하지 않다. 더군다나 IDE 나 단위 테스트에 그다지 도움이 되지 않는 형태이다. 우리는 Mapper 를 사용하는 예제는 이미 시작하기 섹션에서 봤다.

그러므로, 매핑된 구문을 실행하기 위해 좀더 공통적인 방법은 Mapper 클래스를 사용하는 것이다. Mapper 클래스는 SqlSession 메서드에 일치하는 메서드와 간단히 연동된다. 다음의 예제 클래스는 몇가지 메서드 시그니처와 SqlSession 에 매핑하는 방법을 보여준다.

public interface AuthorMapper {
  // (Author) selectOne("selectAuthor",5);
  Author selectAuthor(int id); 
  // (List<Author>) selectList(“selectAuthors”)
  List<Author> selectAuthors();
  
  // (Map<Integer,Author>) selectMap("selectAuthors", "id")
  @MapKey("id")
  List<Author> selectAuthorsAsMap();
  // insert("insertAuthor", author)
  int insertAuthor(Author author);
  // updateAuthor("updateAuthor", author)
  int updateAuthor(Author author);
  // delete("deleteAuthor",5)
  int deleteAuthor(int id);
}

아주 간결하게, 각각의 Mapper 메서드 시그니처는 SqlSession 의 메서드 시그니처와 일치해야만 한다. String 파라미터 ID 가 없지만, 대신 메서드명은 매핑된 구문의 ID 와 같아야 한다.

추가로, 리턴 타입은 기대하는 결과 타입과 일치해야만 한다. 원시타입과 Map, POJO 그리고 자바빈등 대부분의 타입이 지원된다.

참고 Mapper 인터페이스는 어떠한 인터페이스를 구현할 필요가 없고 어떠한 클래스를 확장할 필요도 없다. 메서드 시그니처는 관련된 매핑된 구문을 유일하게 확인하기 위해 사용될 수 있다..

참고 Mapper 인터페이스는 다른 인터페이스를 확장할 수 있다. 적절한 명명공간의 구문은 Mapper 인터페이스에 XML 바인딩을 사용한다. 오직 하나의 제한점은 두개의 인터페이스에 같은 메서드 시그니처를 사용할 수 없다는 것이다.

mapper 메서드에 여러개의 파라미터를 전달 할 수 있다. 여러개의 파라미터를 전달하면, 파라미터 목록의 위치에 따라 명명될 것이다. 예를 들면, #{param1}, #{param2} 기타 등등 이런 식이다. 만약 파라미터의 이름을 변경하고자 한다면, 파라미터의 @Param(“paramName”) 애노테이션을 사용할 수 있다.

쿼리 결과를 제한하기 위해 메서드에 RowBounds 인스턴스를 전달 할 수 있다.

Mapper 애노테이션

이 프레임워크가 만들어진 이후로 MyBatis 는 XML 기반의 프레임워크이다. 설정은 XML 기반이고 매핑된 구문또한 XML 에 정의한다. MyBatis 3 에서는 새로운 추가 옵션이 생겼다. MyBatis 3 은 편리하고 강력한 자바 기반의 설정 API 를 제공한다. 설정 API 는 XML 기반의 MyBatis 설정의 기초가 된다. 이는 새로운 애노테이션 기반의 설정에도 그대로 적용된다. 애노테이션은 소개하는데 많은 시간이 할애하지 않아도 될 정도로 매핑된 구문을 구현하는 간단한 방법을 제공한다.

참고 자바 애노테이션은 복잡하고 유연해야 하는 경우에 대해서는 다소 제한적이다. 조사하는데 많은 시간이 소요됨에도 불구하고, 가장 강력한 MyBatis 매핑은 애노테이션으로 처리되지는 못한다. C# 속성은 이러한 제한사항이 없어서 MyBatis.NET 버전은 XML 대안으로 자바보다 다소 더 풍부한 기능을 제공한다. 하지만 자바 애노테이션 기반의 설정이 장점이 없지는 않다.

사용가능한 애노테이션은 아래에서 설명한다.

애노테이션 대상 XML 요소 설명
@CacheNamespace Class <cache> 명명공간을 위한 캐시 설정 사용가능한 속성들 : implementation, eviction, flushInterval, size 그리고 readWrite.
@CacheNamespaceRef Class <cacheRef> 다른 명명공간의 캐시에 대한 참조 사용가능한 속성들 : value(명명공간의 이름).
@ConstructorArgs Method <constructor> 결과 객체 생성자에 전달되는 결과들 사용가능한 속성들 : value(인자의 배열)
@Arg Method
  • <arg>
  • <idArg>
ConstructorArgs 의 일부로 한개의 생성자 인자 사용가능한 속성들 : id, column, javaType, jdbcType, typeHandler, select 그리고 resultMap. id 속성은 비교하기 위해 사용되는 값이다. XML 에서는 <idArg> 요소와 유사하다.
@TypeDiscriminator Method <discriminator> 결과매핑을 할때 사용될 수 있는 경우에 대한 값들 사용가능한 속성들 : column, javaType, jdbcType, typeHandler, cases. cases 속성은 경우(case)의 배열이다.
@Case Method <case> case 의 값과 매핑 사용가능한 속성들 : value, type, results. results 속성은 Result 의 배열이다. 게다가 이 Case 애노테이션은 Results 애노테이션에서 명시된 ResultMap 와 유사하다.
@Results Method <resultMap> 결과 칼럼이 프로퍼티나 필드에 매핑되는 방법에 대한 상세 설정을 포함하는 결과 매핑의 목록 사용가능한 속성들 : value(Result 애노테이션의 배열)
@Result Method
  • <result>
  • <id>
칼럼이 프로퍼티나 필드에 매핑되는 한개의 결과 매핑 사용가능한 속성들 : id, column, property, javaType, jdbcType, typeHandler, one, many. id 속성은 프로퍼티를 비교할 때 사용할지를 표시하는 boolean 값이다. (XML 에서 <id> 와 유사하다.) one 속성은 한개의 관계(associations)이고, <association> 과 유사하다. many 속성은 collection 이고 <collection> 과 유사하다. 클래스의 명명규칙 충돌을 피하기 위해 명명되었다.
@One Method <association> 복잡한 타입의 한개의 프로퍼티를 위한 매핑이다. 사용가능한 속성들 : select(매핑 구문의 이름, 예를 들어 매퍼 메서드) Note: 조인 매핑은 애노테이션 API 를 통해서는 지원되지 않는다는 것을 알아야 한다. 순환(circular) 참조를 허용하지 않는 자바 애노테이션의 제약사항때문이다.
@Many Method <collection> 복잡한 타입의 collection 프로퍼티를 위한 매핑이다. 사용가능한 속성들 : select(매핑 구문의 이름, 예를 들어 매퍼 메서드) Note: 조인 매핑은 애노테이션 API 를 통해서는 지원되지 않는다는 것을 알아야 한다. 순환(circular) 참조를 허용하지 않는 자바 애노테이션의 제약사항때문이다.
@MapKey Method 리턴 타입이 Map 인 메서드에서 사용된다. 결과 객체의 List 를 객체의 프로퍼티에 기초한 Map 으로 변환하기 위해 사용된다.
@Options Method 매핑 구문의 속성들 이 애노테이션은 매핑된 구문에 속성으로 존재하는 많은 분기(switch)와 설정 옵션에 접근할 수 있다. 각 구문을 복잡하게 만들기 보다, Options 애노테이션으로 일관되고 깔끔한 방법으로 설정 할 수 있게 한다. 사용가능한 속성들 : useCache=true, flushCache=false, resultSetType=FORWARD_ONLY, statementType=PREPARED, fetchSize=-1, timeout=-1, useGeneratedKeys=false, keyProperty=“id”, keyColumn=“”. 자바 애노테이션을 이해하는 것이 중요하다. 자바 애노테이션은 “null”을 셋팅 할 수 없다. 그래서 일단 Options 애노테이션을 사용하면 각각의 속성은 디폴트 값을 사용하게 된다. 디폴트 값이 기대하지 않은 결과를 만들지 않도록 주의해야 한다. keyColumn 은 키 칼럼이 테이블의 첫번째 칼럼이 아닌 특정 데이터베이스에서만(PostgreSQL 같은) 필요하다..
  • @Insert
  • @Update
  • @Delete
  • @Select
Method
  • <insert>
  • <update>
  • <delete>
  • <select>
각각의 애노테이션은 실행하고자 하는 SQL 을 표현한다. 각각 문자열의 배열(또는 한개의 문자열)을 가진다. 문자열의 배열이 전달되면, 각각 공백을 두고 하나로 합친다. 자바 코드에서 SQL 을 만들때 발행할 수 있는 “공백 누락” 문제를 해결하도록 도와준다. 사용가능한 속성들 : value(한개의 SQL 구문을 만들기 위한 문자열의 배열)
  • @InsertProvider
  • @UpdateProvider
  • @DeleteProvider
  • @SelectProvider
Method
  • <insert>
  • <update>
  • <delete>
  • <select>
실행시 SQL 을 리턴할 클래스명과 메서드명을 명시하도록 해주는 대체수단의 애노테이션이다. 매핑된 구문을 실행할 때 MyBatis 는 클래스의 인스턴스를 만들고, 메서드를 실행한다. 메서드는 파라미터 객체를 받을 수도 있다. 사용가능한 속성들 : type, method. type 속성은 클래스의 패키지 경로를 포함한 전체 이름이다. 메서드는 클래스의 메서드명이다. Note: 이 섹션은 SelectBuilder 클래스에 대한 설명으로, 동적 SQL 을 좀더 깔끔하고 읽기 쉽게 만드는데 도움이 될 수 있다.
@Param Parameter N/A 매퍼 메서드가 여러개의 파라미터를 가진다면, 이 애노테이션은 이름에 일치하는 매퍼 메서드 파라미터에 적용된다. 반면에 여러개의 파라미터는 순서대로 명명된다. 예를 들어, #{param1}, #{param2} 등이 디폴트다. @Param(“person”) 를 사용하면, 파라미터는 #{person} 로 명명된다.
@SelectKey Method <selectKey> 이 애노테이션은 @Insert, @InsertProvider, @Update 또는 @UpdateProvider 애노테이션을 사용하는 메서드에서 <selectKey>와 똑같다. 다른 메서드에서는 무시된다. @SelectKey 애노테이션을 명시하면, MyBatis 는 @Options 애노테이션이나 설정 프로퍼티를 통해 셋팅된 key 프로퍼티를 무시할 것이다. 사용가능한 속성들 : statement 는 실행할 SQL 구문을 만드는 문자열의 배열이다. keyProperty 는 새로운 값으로 수정될 파라미터 객체의 프로퍼티이다. SQL 이 insert 전후에 실행되는 것을 나타내기 위해 true 나 false 가 되어야 한다. resultType 은 keyProperty 의 자바 타입이다. statementType=PREPARED.
@ResultMap Method N/A 이 애노테이션은 @Select 또는 @SelectProvider 애노테이션을 위해 XML 매퍼의 <resultMap> 요소의 id 를 제공하기 위해 사용된다. XML 에 정의된 결과 매핑을 재사용하도록 해준다. 이 애노테이션은 @Results 나 @ConstructorArgs 를 오버라이드 할 것이다.
@ResultType Method N/A 이 애노테이션은 결과 핸들러를 사용할때 사용한다. 이 경우 리턴타입은 void이고 마이바티스는 각각의 레코드 정보를 가지는 객체의 타입을 결정하는 방법을 가져야만 한다. XML 결과매핑이 있다면 @ResultMap 애노테이션을 사용하자. 결과타입이 XML에서 <select> 엘리먼트에 명시되어 있다면 다른 애노테이션이 필요하지 않다. 결과타입이 XML에서 <select> 엘리먼트에 명시되어 있지 않은 경우에 이 애노테이션을 사용하자. 예를들어, @Select 애노테이션이 선언되어 있다면 메소드는 결과 핸들러를 사용할 것이다. 결과 타입은 void여야만 하고 이 애노테이션(이나 @ResultMap)을 반드시 사용해야 한다. 이 애노테이션은 메소드 리턴타입이 void가 아니라면 무시한다.
Mapper 애노테이션 예제

이 예제는 insert 하기전에 일련번호를 가져오기 위해 @SelectKey 애노테이션을 사용하는 것을 보여준다.

@Insert("insert into table3 (id, name) values(#{nameId}, #{name})")
@SelectKey(statement="call next value for TestSequence", keyProperty="nameId", before=true, resultType=int.class)
int insertTable3(Name name);

이 예제는 insert 한 후에 값을 가져오기 위해 @SelectKey 애노테이션을 사용하는 것으로 보여준다.

@Insert("insert into table2 (name) values(#{name})")
@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
int insertTable2(Name name);