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 인터페이스 구현:
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 추상 클래스 상속 (권장):
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 구현:
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)에 등록:
<configuration>
<typeHandlers>
<typeHandler handler="com.example.typehandler.LocalDateTypeHandler" javaType="java.time.LocalDate" jdbcType="DATE"/>
</typeHandlers>
</configuration>
2. Java Config에 등록:
@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 어노테이션으로 등록
public class User {
@TypeHandler(LocalDateTypeHandler.class)
private LocalDate localDate;
}
4. Result Map에서 typeHandler 속성으로 등록
<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 예시:
<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 인터페이스 예시:
public interface UserMapper {
void insertUser(User user);
User selectUser(int id);
}
User 클래스 예시:
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 |