由于数据库中定义了一个枚举类型,mybatis generator默认生成的类类型为String,但是我想生成枚举类型,于是自定义typeHandler类型处理。
数据库的枚举类型字段定义如下:
create type productclass as enum('h','o','a','f')
1、定义枚举类
/**
* Created by bo on 2019/1/7.
* class类别
*/
public enum ClassEnum {
APP("a"), OS("o"), HARDWARE("h"), FIRMWARE("f");
private String type;
ClassEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public static ClassEnum getClassEnum(String type) {
if (type.equals("a")) {
return APP;
} else if (type.equals("o")) {
return OS;
} else if (type.equals("h")) {
return HARDWARE;
} else if (type.equals("f")) {
return FIRMWARE;
}
return null;
}
}
2、配置mybatis generator覆盖默认生成类型,使生成的java类对应的字段类型为ClassEnum类型
<table tableName="product" domainObjectName="Product">
<columnOverride column="class" property="classes" javaType="com.data.typehandler.ClassEnum"/>
</table>
3、自定义typeHandler
/**
* Created by bo on 2019/1/7.
*/
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(ClassEnum.class)
public class ClassEnumTypeHandler extends BaseTypeHandler<ClassEnum> {
@Override
public void setNonNullParameter(PreparedStatement ps, int index, ClassEnum classEnum, JdbcType jdbcType) throws SQLException {
ps.setString(index, classEnum.getType());
}
@Override
public ClassEnum getNullableResult(ResultSet rs, String field) throws SQLException {
return ClassEnum.getClassEnum(rs.getString(field));
}
@Override
public ClassEnum getNullableResult(ResultSet rs, int index) throws SQLException {
return ClassEnum.getClassEnum(rs.getString(index));
}
@Override
public ClassEnum getNullableResult(CallableStatement cs, int index) throws SQLException {
return ClassEnum.getClassEnum(cs.getString(index));
}
}
4、在mapper.xml的reusltMap中指定typeHandler
<result property="classes" column="class" typeHandler="com.data.typehandler.ClassEnumTypeHandler"/>
PostgreSQL还可以允许你传递一个String类型的字符来进行对数据库中枚举类型数据的插入或者更新,但是使用占位符时必须在字段处显示的执行数据库的枚举类型,否则会报错,如下:
<update id="updateProduct">
update product set "class" = #{classes}
where id = 1
</update>
Caused by: org.postgresql.util.PSQLException: 错误: 字段 "class" 的类型为 productclass, 但表达式的类型为 character varying
建议:你需要重写或转换表达式
显示的指定字段的数据库枚举类型,就不会报错了。
<update id="updateProduct">
update product set "class" = #{classes}::productclass
where id = 1
</update>
不使用占位符时,直接执行sql,是可以的,例如:
<update id="updateProduct">
update product set "class" = 'h'
where id = 1
</update>
符合“PostgreSQL还可以允许你传递一个String类型的字符来进行对数据库中枚举类型数据的插入或者更新”。但是我没搞明白为啥使用占位符不行,感觉还是jdbc这块出了问题。
参考: