我们在使用postgres数据库时会使用到json格式来存放一些格式不固定的字段,postgres支持json和jsonb两种格式,两者的区别以后再说,今天说一下结合mybatis的使用方法:
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> {
private static final PGobject jsonObject = new PGobject();
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {
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);
}
}
jsonb类型字段对应的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 JsonbTypeHandler extends BaseTypeHandler <Object> {
private static final PGobject jsonObject = new PGobject();
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {
jsonObject.setType("jsonb");
jsonObject.setValue(JsonUtil.toJsonString(o));
preparedStatement.setObject(i,jsonObject);
}
@Override
public Object getNullableResult(ResultSet resultSet, String s) throws SQLException {
if(null != resultSet.getString(s)){
return JsonUtil.fromJson(resultSet.getString(s), Object.class);
}
return null ;
}
@Override
public Object getNullableResult(ResultSet resultSet, int i) throws SQLException {
if(null != resultSet.getString(i)){
return JsonUtil.fromJson(resultSet.getString(i), Object.class);
}
return null ;
}
@Override
public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
if(null != callableStatement.getString(i)){
return JsonUtil.fromJson(callableStatement.getString(i), Object.class);
}
return null ;
}
}
"BaseResultMap" type="com.jun.test.handler.mapper.entity.EventLog">
"uuid" jdbcType="VARCHAR" property="uuid" />
"device_name" jdbcType="VARCHAR" property="deviceName" />
"status" jdbcType="SMALLINT" property="status" />
"extend" jdbcType="OTHER" property="extend" typeHandler="com.jun.test.handler.JsonTypeHandler" />
...
注意在insert和update语句等用到json字段的属性都要手动去引用自定义的typeHandler。
insert into ec.event_log (uuid,
device_name, resource_name, status,
extend
)
values (#{uuid,jdbcType=VARCHAR},
#{deviceName,jdbcType=VARCHAR}, #{status,jdbcType=SMALLINT},
#{extend,jdbcType=OTHER,typeHandler=com.jun.test.handler.JsonTypeHandler}
)
想要进行解析时,可以获取到该Object对象后,先转成json字符串,再转成对应的对象,如下:
Extend extend = JsonUtil.parser(JsonUtil.toJson(eventLog.getExtend ()), Extend .class);