【发布时间】:2019-06-14 07:48:29
【问题描述】:
我需要使用mybatis对Set<MyEnum>进行序列化和反序列化。序列化时效果很好,但反序列化时得到Set<String>。这是我的代码:
mybatis-config.xml:
<typeHandlers>
<typeHandler handler="com.my.JsonTypeHandler" javaType="com.my.MyEnum"/>
<typeHandler handler="com.my.JsonTypeHandler" javaType="java.util.Set"/>
</typeHandlers>
我的枚举:
@Getter
@AllArgsConstructor
public enum MyEnum {
MILEAGE(1),
DRIVE_DURATION(2)
;
private int value;
@JsonCreator
public static MyEnum fromName(String name) {
return MyEnum.valueOf(name);
}
}
mapper.xml:
<select id="queryByParam" parameterType="com.my.DaoQueryParam" resultType="com.my.model.Product">
select * from product
<where>
product_id = #{assetProductId}
</where>
</select>
<insert id="insert" parameterType="com.my.model.Product">
insert into product
(some code here)
</insert>
产品:
@Data // lombok
public class Product {
private Set<MyEnum> myEnums;
}
JsonTypeHandler:
public class JsonTypeHandler<T extends Object> extends BaseTypeHandler<T> {
private static final ObjectMapper mapper = new ObjectMapper()
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
private Class<T> clazz;
public JsonTypeHandler(Class<T> clazz) {
if (clazz == null) throw new IllegalArgumentException("Type argument cannot be null");
this.clazz = clazz;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, this.toJson(parameter));
}
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
return this.toObject(rs.getString(columnName), clazz);
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return this.toObject(rs.getString(columnIndex), clazz);
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return this.toObject(cs.getString(columnIndex), clazz);
}
private String toJson(T object) {
try {
return mapper.writeValueAsString(object);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private T toObject(String content, Class<?> clazz) {
if (content != null && !content.isEmpty()) {
try {
return (T) mapper.readValue(content, clazz);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
return null;
}
}
}
mysql中myEnums列的对应类型是VARCHAR。
序列化时,我得到了令人满意的结果,例如。 ["MILEAGE"]。
反序列化时,它不会引发任何错误,但 Product 中的 myEnums 字段实际上是 Set<String>。
我尝试修改mybatis-config.xml:
<typeHandlers>
<typeHandler handler="com.my.JsonTypeHandler" javaType="java.util.Set<MyEnum>"/>
</typeHandlers>
但发生错误并说 javaType 中不允许使用“
【问题讨论】:
-
尝试从
javaType="java.util.Set<MyEnum>"中删除<MyEnum>。 -
是的,我一开始就是这么做的。