Mybatis를 처음 사용합니다. 최근에 나는 커스텀 generic 타입을 사용했다 .Hander, bean 속성이 테이블의 컬럼 이름과 같을 때, select는 ClassCastException을 발생시킬 것이다. 다음Mybatis가 사용자 정의 제네릭 typehandler를 사용할 때 bean 속성 이름과 테이블의 열이 동일하면 select가 ClassCastException을 발생시킵니다.
는구성을
의 MyBatis-의 configuration.xml
<typeHandlers>
<typeHandler handler="com.sut.util.enumerate.mybatis.GenericEnumUserType"
javaType="com.sut.util.meta.WhetherTypeEnum" jdbcType="CHAR"/>
<typeHandler handler="com.sut.util.enumerate.mybatis.GenericEnumUserType"
javaType="com.sut.util.meta.SexTypeEnum" jdbcType="CHAR" />
<typeHandler handler="com.sut.util.enumerate.mybatis.GenericEnumUserType"
javaType="com.sut.util.meta.ArticleTypeEnum" jdbcType="CHAR" />
<typeHandler handler="com.sut.util.enumerate.mybatis.GenericEnumUserType"
javaType="com.sut.util.meta.EducationLevelEnum" jdbcType="CHAR" />
<typeHandler handler="com.sut.util.enumerate.mybatis.GenericEnumUserType"
javaType="com.sut.util.meta.ServiceLevelEnum" jdbcType="CHAR" />
<typeHandler handler="com.sut.util.enumerate.mybatis.GenericEnumUserType"
javaType="com.sut.util.meta.ServiceTypeEnum" jdbcType="CHAR" />
<typeHandler handler="com.sut.util.enumerate.mybatis.GenericEnumUserType"
javaType="com.sut.util.meta.StaffLevelEnum" jdbcType="CHAR" />
<typeHandler handler="com.sut.util.enumerate.mybatis.GenericEnumUserType"
javaType="com.sut.util.meta.ArticleStatusEnum" jdbcType="CHAR" />
<typeHandler handler="com.sut.util.enumerate.mybatis.GenericEnumUserType"
javaType="com.sut.util.meta.HealthyStatusEnum" jdbcType="CHAR" />
</typeHandlers>
staffMapper.xml
<resultMap type="com.sut.persist.entity.Staff" id="staff">
<id property="id" javaType="int" column="id" />
<result property="staffName" javaType="String" column="STAFF_NAME" />
<result property="imgPath" javaType="String" column="IMG_PATH" />
<result property="staffLevel" javaType="com.sut.util.meta.StaffLevelEnum" column="LEVEL"
typeHandler="com.sut.util.enumerate.mybatis.GenericEnumUserType" jdbcType="CHAR"/>
<result property="birthDate" javaType="java.util.Date" column="BIRTH_DATE" />
<result property="address" javaType="String" column="address" />
<result property="healthyStatus" javaType="com.sut.util.meta.HealthyStatusEnum" column="HEALTHY_STATUS"
typeHandler="com.sut.util.enumerate.mybatis.GenericEnumUserType" jdbcType="CHAR" />
<result property="education" column="education" typeHandler="com.sut.util.enumerate.mybatis.GenericEnumUserType" />
<result property="workYears" javaType="integer" column="WORK_YEARS" />
<result property="selfIntroduction" javaType="String" column="SELF_INTRODUCTION" />
<result property="cert" javaType="String" column="CERT" />
<result property="remark" javaType="String" column="REMARK" />
<result property="serviceType" javaType="com.sut.util.meta.ServiceTypeEnum" column="SERVICE_TYPE"
typeHandler="com.sut.util.enumerate.mybatis.GenericEnumUserType" />
<result property="mobile" javaType="String" column="MOBILE" />
<result property="qqNumber" javaType="String" column="QQ_NUMBER" />
<result property="webchatNumber" javaType="String" column="WEBCHAT_NUMBER" />
<result property="webchatQrcode" javaType="String" column="WEBCHAT_QRCODE" />
</resultMap>
<!-- query user by id -->
<select id="getById" parameterType="long" resultMap="staff">
select
staff_id,
staff_name,
img_path,
level as staffLevel,
birth_date,
address,
healthy_status as healthyStatus,
education as education,
work_years,
self_introduction,
cert,
remark,
service_type as serviceType,
mobile,
qq_number,
webchat_number,
webchat_qrcode
from bbs_staff where staff_id = #{id}
Staff.java 있습니다
,210com.sut.util.enumerate.mybatis.GenericEnumUserType : 일반 TypeHandler 사용시
Struts has detected an unhandled exception:
Messages:
[email protected]
Could not set property 'education' of 'class com.sut.persist.entity.Staff' with value '[email protected]' Cause: java.lang.IllegalArgumentException: [email protected]
nested exception is org.apache.ibatis.reflection.ReflectionException: Could not set property 'education' of 'class com.sut.persist.entity.Staff' with value '[email protected]' Cause: java.lang.IllegalArgumentException: [email protected]
의 MyBatis 문서 상기 다음 getById 메소드를 호출 할 때, 예외를 발생한다
public class GenericEnumUserType<E extends StringEnumTypeImp> extends BaseTypeHandler<E>{
private static final Logger LOG = LoggerFactory.getLogger(GenericEnumUserType.class);
//mybatis will pass actual class when constructing TypeHandler
private Class<E> type;
private static final String fromStringCode = "fromStringCode";
public GenericEnumUserType(Class<E> type){
Preconditions.checkNotNull(type, "Type argument cannot be null");
this.type = type;
}
/**
* @see org.apache.ibatis.type.BaseTypeHandler#setNonNullParameter(java.sql.PreparedStatement, int, java.lang.Object, org.apache.ibatis.type.JdbcType)
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, StringEnumTypeImp parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter.getStoreValue());
}
/**
* getResult and use reflect
* @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.ResultSet, java.lang.String)
*/
@Override
@SuppressWarnings("unchecked")
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
LOG.info("return type is : {}", type);
String storeValue = rs.getString(columnName);
Preconditions.checkNotNull(type, "Type argument cannot be null");
try {
Method fromMethod = type.getMethod(fromStringCode, String.class);
return (E) fromMethod.invoke(null, storeValue);
} catch (IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
*
* @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.ResultSet, int)
*/
@SuppressWarnings("unchecked")
@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
LOG.info("return type is {}", type);
String storeValue = rs.getString(columnIndex);
Preconditions.checkNotNull(type, "Type argument cannot be null");
try {
Method fromMethod = type.getMethod(fromStringCode, String.class);
return (E) fromMethod.invoke(null, storeValue);
} catch (IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* not used
* @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.CallableStatement, int)
*/
@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
try {
return type.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
JavaType에 의해 jdbcType가 null 일지라도, 올바른 TypeHandler를 얻습니다. 구성을 세 번 확인하고 소스 코드를 디버깅했습니다. 그런 다음 ResultSetWrapper가 mappedColumns 및 UnmappedColumns에 열을 분리한다는 것을 알아 냈습니다. mappedColumns는 그렇지 않으므로 unmappedColumns가 올바른 TypeHandler를 반환합니다. 나는 이것이 왜 일어나는 지 궁금하다. 이 버그 또는 내 구성이 올바르지 않습니다.
환경 :
의 MyBatis : 3.4.1
MySQL은 : 5.6
어떤 도움을 이해할 수있을 것이다! 실제 mapper.xml에서
안녕하세요, (MyBatis로 그것을 할 수 있습니다) w. com.sut.util.enumerate.mybatis.GenericEnumUserType의 구현도 제공해 주시겠습니까? – hakamairi
답장을 보내 주셔서 감사합니다. 'GenericEnumUserType' 코드를 추가했습니다 .. –
Staff 클래스도 추가 할 수 있습니까? – hakamairi