简介
在使用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;}@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, this.toJson(parameter));}@Overridepublic T getNullableResult(ResultSet rs, String columnName) throws SQLException {return this.toObject(rs.getString(columnName), clazz);}@Overridepublic T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return this.toObject(rs.getString(columnIndex), clazz);}@Overridepublic 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}