Mybatis에서 TypeHandler 사용하기

2025. 1. 24. 07:34·개발/Mybatis

MyBatis에서 TypeHandler는 Java 타입과 JDBC 타입을 변환하는 역할을 한다. 즉, Java 객체의 필드를 데이터베이스 컬럼에 매핑하거나, 데이터베이스 컬럼 값을 Java 객체의 필드로 매핑할 때 데이터 타입 간의 변환을 처리한다.

TypeHandler가 필요한 경우:

  • MyBatis가 기본적으로 지원하지 않는 사용자 정의 타입을 사용할 때
  • 특정 데이터 타입의 변환 방식을 커스터마이징하고 싶을 때 (예: java.util.Date를 yyyyMMdd 형식의 문자열로 변환)
  • 데이터베이스의 특정 데이터 타입(예: JSON, Enum)을 Java 객체로 매핑하고 싶을 때

TypeHandler 구현 방법:

TypeHandler를 구현하려면 org.apache.ibatis.type.TypeHandler 인터페이스를 구현하거나, org.apache.ibatis.type.BaseTypeHandler 추상 클래스를 상속받아야 한다.

1. org.apache.ibatis.type.TypeHandler 인터페이스 구현:

Java
 
public interface TypeHandler<T> {

  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

  T getResult(ResultSet rs, String columnName) throws SQLException;

  T getResult(ResultSet rs, int columnIndex) throws SQLException;

  T getResult(CallableStatement cs, int columnIndex) throws SQLException;

}
  • setParameter(): PreparedStatement에 파라미터를 설정한다.
  • getResult(): ResultSet 또는 CallableStatement에서 값을 가져와 Java 객체로 변환한다.

2. org.apache.ibatis.type.BaseTypeHandler 추상 클래스 상속 (권장):

Java
 
public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> {

  // ...

  public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

  public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;

  public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;

  public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;

}
  • BaseTypeHandler를 상속하면 null 값 처리를 MyBatis가 자동으로 처리해주기 때문에, setNonNullParameter()와 getNullableResult() 메서드만 구현하면 된다.

예시: java.time.LocalDate를 위한 TypeHandler 구현:

Java
 
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.*;
import java.time.LocalDate;

public class LocalDateTypeHandler extends BaseTypeHandler<LocalDate> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LocalDate parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setDate(i, Date.valueOf(parameter));
    }

    @Override
    public LocalDate getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Date date = rs.getDate(columnName);
        return date != null ? date.toLocalDate() : null;
    }

    @Override
    public LocalDate getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Date date = rs.getDate(columnIndex);
        return date != null ? date.toLocalDate() : null;
    }

    @Override
    public LocalDate getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Date date = cs.getDate(columnIndex);
        return date != null ? date.toLocalDate() : null;
    }
}

TypeHandler 등록:

TypeHandler를 사용하려면 MyBatis 설정 파일(mybatis-config.xml) 또는 Java Config에 등록해야 한다.

1. XML 설정 파일(mybatis-config.xml)에 등록:

XML
 
<configuration>
  <typeHandlers>
    <typeHandler handler="com.example.typehandler.LocalDateTypeHandler" javaType="java.time.LocalDate" jdbcType="DATE"/>
  </typeHandlers>
</configuration>

2. Java Config에 등록:

Java
 
@Configuration
public class MyBatisConfig {

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);

        // TypeHandler 등록
        factoryBean.setTypeHandlers(new TypeHandler[]{new LocalDateTypeHandler()});

        return factoryBean.getObject();
    }
}

3. Mapper에서 @TypeHandler 어노테이션으로 등록

Java
 
public class User {
    @TypeHandler(LocalDateTypeHandler.class)
    private LocalDate localDate;
}

4. Result Map에서 typeHandler 속성으로 등록

XML
 
<resultMap id="userResultMap" type="User">
    <result property="localDate" column="ld" typeHandler="com.example.typehandler.LocalDateTypeHandler"/>
</resultMap>

TypeHandler 사용:

TypeHandler를 등록한 후에는, Mapper XML 파일이나 Mapper 인터페이스에서 해당 Java 타입과 JDBC 타입을 사용할 수 있다.

Mapper XML 예시:

XML
 
<insert id="insertUser" parameterType="User">
    INSERT INTO users (name, birth_date)
    VALUES (#{name}, #{birthDate})
</insert>

<select id="selectUser" resultType="User">
    SELECT name, birth_date
    FROM users
    WHERE id = #{id}
</select>

Mapper 인터페이스 예시:

Java
 
public interface UserMapper {
    void insertUser(User user);
    User selectUser(int id);
}

User 클래스 예시:

Java
 
public class User {
    private String name;
    private LocalDate birthDate;

    // getters and setters
}

위 예시에서 birthDate 필드는 java.time.LocalDate 타입이고, LocalDateTypeHandler를 통해 DATE JDBC 타입과 매핑된다.

 

저작자표시 비영리 변경금지 (새창열림)

'개발 > Mybatis' 카테고리의 다른 글

Mybatis resultMap 사용법  (0) 2025.01.24
Mybatis란?  (0) 2025.01.24
Mybatis에서 Oracle과 Java의 일반적인 데이터 타입 매핑  (0) 2025.01.24
'개발/Mybatis' 카테고리의 다른 글
  • Mybatis resultMap 사용법
  • Mybatis란?
  • Mybatis에서 Oracle과 Java의 일반적인 데이터 타입 매핑
함수형 인간
함수형 인간
잘 까먹는 개발자의 두뇌 확장 장치
  • 함수형 인간
    개발 기록 노트
    함수형 인간
  • 글쓰기 관리
  • 전체
    오늘
    어제
    • 글 목록 (84)
      • 기타 (1)
      • 개발 (82)
        • Java (6)
        • Javascript (1)
        • Spring (20)
        • jQuery (0)
        • Git (0)
        • servlet (11)
        • JSP (6)
        • HTML (0)
        • CSS (10)
        • SQL (9)
        • JSTL (3)
        • Mybatis (4)
        • Design Patterns (0)
        • HTTP (2)
        • Devtools (0)
        • IntelliJ (5)
        • JDBC (1)
        • Lombok (3)
        • Logging (1)
      • 책 리뷰 (0)
  • hELLO· Designed By정상우.v4.10.3
함수형 인간
Mybatis에서 TypeHandler 사용하기
상단으로

티스토리툴바