Mybatisを初めて使用しています。最近、私はカスタムのジェネリック型のHanderを使用しました.Beanのプロパティがテーブルの列名と同じ場合、selectはClassCastExceptionを発生させます。Mybatisがカスタムジェネリック型ハンドラを使用していて、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です
com.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を取得します。設定を3回チェックし、ソースコードをデバッグしました。次に、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