简介
在使用MyBatis的过程中,会有这样的需求:POJO里有个属性是非基本数据类型,在DB存储时我们想存的是json格式的字符串,从DB拿出来时想直接映射成目标类型,也即json格式的字符串字段与Java类的相互类型转换。
解决方式是为每一个类写一个TypeHandler,但是这样过于繁琐。
引入泛型,写一个通用的TypeHandler。
代码
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author ConnorSong
* @date 2021/1/19 3:33 下午
*/
public class JsonTypeHandler<T> extends BaseTypeHandler<T> {
private static final ObjectMapper mapper = new ObjectMapper();
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;
}
}
// static {
// mapper.configure(Feature.WRITE_NULL_MAP_VALUES,false);
// mapper.setSerializationInclusion(WritableTypeId.Inclusion.NON_NULL);
// }
}
使用方法
查询:
在resultMap中的字段后面注明typeHandler,也可以加上javaType,指定映射的对象。
<result column="metrics" jdbcType="JSON" property="chartMetrics" typeHandler="com.server.configuration.mybatis.JsonTypeHandler" />
更新和插入:
也是需要指定参数的typeHandler
#{metrics,typeHandler=com.server.configuration.mybatis.JsonTypeHandler}