开发TypeHandler
如果数据库字段是字符类型,可以直接使用Mybatis-Plus
内置的JacksonTypeHandler
,如果是像PostgreSQL
数据库的JSONB
类型,则需要自定义开发一个TypeHandler
,可以继承JacksonTypeHandler
,然后覆写父类的方法,代码如下:
/**
* PostgreSQL数据库中的JSON、JSONB字段类型的映射
*
* @author tangheng
*/
@MappedTypes({Object.class})
@MappedJdbcTypes(JdbcType.OTHER)//JSONB对应JdbcType.OTHER
public class JsonbTypeHandler extends JacksonTypeHandler {
private static final PGobject jsonObject = new PGobject();
private static final String JSONB = "jsonb";
private static final String JSON = "json";
public JsonbTypeHandler(Class<?> type) {
super(type);
}
/**写数据库时,把java对象转成JSONB类型*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
if (ps != null) {
jsonObject.setType(JSONB);
jsonObject.setValue(toJson(parameter));
ps.setObject(i, jsonObject);
}
}
/**读数据时,把JSONB类型的字段转成java对象*/
@Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
Object v = rs.getObject(columnName);
return convertDbToJavaObject(v);
}
/**读数据时,把JSONB类型的字段转成java对象*/
@Override
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Object v = rs.getObject(columnIndex);
return convertDbToJavaObject(v);
}
/**读数据时,把JSONB类型的字段转成java对象*/
@Override
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Object v = cs.getObject(columnIndex);
return convertDbToJavaObject(v);
}
/**读数据时,把JSONB类型的字段转成java对象*/
private Object convertDbToJavaObject(Object v) {
if(Objects.isNull(v)) {
return v;
}
if (!PGobject.class.isAssignableFrom(v.getClass())) {
return v;
}
PGobject p = (PGobject) v;
if(!StringUtils.equalsAnyIgnoreCase(p.getType(), JSONB, JSON)) {
return v;
}
String pv = p.getValue();
if(StringUtils.isBlank(pv)) {
return v;
}
return parse(p.getValue());
}
}
使用TypeHandler
- 在库表实体类上加的
@TableName
的注解,设置autoResultMap
属性 @TableField
注解指定typeHandler
@TableName(value = "t_user", autoResultMap = true)
public class UserPo {
@TableField(value = "user_jobs", typeHandler = JsonbTypeHandler.class)
private List<UserJob> userJobs;
@NoArgsConstructor
@AllArgsConstructor
@Data
public static class UserJob {
private String id;
private String name;
}
}
总结
- 使用
JacksonTypeHandler
可以帮开发者自动处理json
格式与java
对象之间的映射关系,不需要每次手动做序列化和反序列化的工作了。 - 如果使用的数据库有自己特有的字段类型,也可以自定义开发一个
TypeHandler
,达到自动转换的目的。