이제 문제는 User가 가진Role 타입의 객체를 어떻게 테이블의 문자열 컬럼인 role에 연결할 것인가가 남았다. 이를 위해 사용자 정의의 TypeHandler가 필요하다.
RoleTypeHandler 작성
사용자정의 TypeHandler를 작성하기 위해서는 TypeHandler interface를 구현해주면 된다. abstract method 3개를 구현해주면 되는데 역할은 주석을 참조하자.
TypeHandler를 작성한 후 어떤 클래스에 적용할 것인지를 설정하기 위해서 @MappedTypes 애너테이션을 이용한다.
package com.quietjun.oauthtest.model.typehandlers;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
import com.quietjun.oauthtest.model.dto.Role;
@MappedTypes(Role.class)
public class RoleTeypHandler implements TypeHandler<Role> {
@Override
// 지정된 타입의 어떤 값을 DB에 저장할 것인가?
public void setParameter(PreparedStatement ps, int i, Role parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter.getKey());
}
@Override
// 컬럼 이름 기반으로 조회된 값을 활용해서 실제 반환할 객체 구성하기
public Role getResult(ResultSet rs, String columnName) throws SQLException {
String roleKey = rs.getString(columnName);
return getRole(roleKey);
}
@Override
// 컬럼 index 기반으로 조회된 값을 활용해서 실제 반환할 객체 구성하기
public Role getResult(ResultSet rs, int columnIndex) throws SQLException {
String roleKey = rs.getString(columnIndex);
return getRole(roleKey);
}
@Override
// Callablestatement에서 컬럼 index 기반으로 조회된 값을 활용해서 실제 반환할 객체 구성하기
public Role getResult(CallableStatement cs, int columnIndex) throws SQLException {
String roleKey = cs.getString(columnIndex);
return getRole(roleKey);
}
// 실제 객체를 구성하는 메서드
private Role getRole(String roleKey) {
Role role = null;
switch (roleKey) {
case "ROLE_USER":
role = Role.USER;
break;
default:
role = Role.GUEST;
break;
}
return role;
}
}
MyBatis에 TypeHandler 설정
작성한 Handler는 MyBatis에 등록해주면 되는데 사용하는 플랫폼에 따라 다양한 방법으로 처리가 가능하다.