使用mybatis中的自定义TypeHandler处理PostgreSQL中的Json类型字段
业务扩展字段在PostgreSQL数据库中经常会使用json格式的数据来存储,然而mybatis默认是没有实现json类型字段对应的TypeHandler,所以一般我们需要自定义mybatis的TypeHandler。
如下是mybatis中json类型字段对应的TypeHandler的一个简单实现:
import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedTypes; import org.postgresql.util.PGobject; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @MappedTypes({Object.class}) public class JsonTypeHandler extends BaseTypeHandler<Object> { @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {
PGobject jsonObject = new PGobject(); jsonObject.setType("json"); jsonObject.setValue(JsonUtil.toJsonString(o)); preparedStatement.setObject(i, jsonObject); } @Override public Object getNullableResult(ResultSet resultSet, String s) throws SQLException { return JsonUtil.fromJson(resultSet.getString(s), Object.class); } @Override public Object getNullableResult(ResultSet resultSet, int i) throws SQLException { return JsonUtil.fromJson(resultSet.getString(i), Object.class); } @Override public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return JsonUtil.fromJson(callableStatement.getString(i), Object.class); } }
除了编写TypeHandler外,还需要在xml映射文件中做如下配置:
<resultMap id="BaseResultMap" type="com.test.entity.EventLog"> <id column="uuid" jdbcType="VARCHAR" property="uuid"/> <result column="payload" jdbcType="OTHER" property="payload" typeHandler="com.test.dao.typehandler.JsonTypeHandler"/> </resultMap>
<insert id="insert" parameterType="com.test.entity.EventLog"> insert into "test".event_log (uuid,payload) values (#{uuid,jdbcType=VARCHAR},#{payload,jdbcType=OTHER,typeHandler=com.test.dao.typehandler.JsonTypeHandler}) </insert>
使用时,获取到该Object对象后,可先转成json字符串,再转成对应的对象,如下:
EventLogPayload eventLogPayload = JsonUtil.parser(JsonUtil.toJson(eventLog.getPayload()), EventLogPayload.class);