1.字段映射到对象类型
a.创建handler实现org.apache.ibatis.type.BaseTypeHandler
import com.google.gson.Gson; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.*; public class ObjectHandler extends BaseTypeHandler<Object> { private static final Gson GSON = new Gson(); @Override public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { if (parameter == null) { ps.setNull(i, Types.VARCHAR); } else { ps.setString(i, GSON.toJson(parameter)); } } @Override public Object getNullableResult(ResultSet rs, String columnName) throws SQLException { Object convert = convert(rs.getString(columnName)); return convert; } @Override public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException { Object convert = convert(rs.getString(columnIndex)); return convert; } @Override public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { Object convert = convert(cs.getString(columnIndex)); return convert; } private static Object convert(final String columnValue) { return GSON.fromJson(columnValue, Object.class); } }
b.mapper文件中引用
1).对于select操作,在 resultMap 中进行result配置,指定 typeHandler 即可生效
<result property="info" jdbcType="VARCHAR" column="info" typeHandler="com.tencent.iask.util.ObjectHandler"/>
2).对于更新或查询操作,需要在sql中指定
<insert id="createTask"> INSERT INTO `task` (`id`,`project`, `priority`, `info`) VALUES (#{id},#{project},#{priority}, #{info,typeHandler=ObjectHandler}); </insert>
2. 使用了typehandler找不到构造函数的问题
Caused by: org.apache.ibatis.executor.ExecutorException: No constructor found in com.model.Task matching [java.lang.Integer, java.lang.String, java.lang.Integer, java.lang.String]
我的Task类,定义如下(info字段映射的数据库字段类型为varchar):
@Slf4j @Data @AllArgsConstructor public class Task { private Integer id; private String project; private int priority; private Object info; }
原因为:mybatis默认使用无参构造函数,如果没有此函数会根据数据库字段类型寻找有参构造函数,此时,如果对象只有成员列表对应有参构造函数,那么会报找不到构造函数的错误,因此在使用typehandler时,最好给数据类型一个无参构造函数。