【Mybatis-Plus】PostgreSQL之JSONB自动映射对象

开发TypeHandler

如果数据库字段是字符类型,可以直接使用Mybatis-Plus内置的JacksonTypeHandler,如果是像PostgreSQL数据库的JSONB类型,则需要自定义开发一个TypeHandler,可以继承JacksonTypeHandler,然后覆写父类的方法,代码如下:

java 复制代码
/**
 * 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
java 复制代码
@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,达到自动转换的目的。
相关推荐
FungLeo21 小时前
成为全栈·基础补充·数据库迁移与事务:数据结构怎样安全演进
mysql·postgresql·sqlite·数据一致性·数据库事务·数据库迁移·成为全栈
code2cat21 小时前
【随笔】结构化输出:JSON格式过关,业务数据就能入库吗
json·大语言模型
bksczm1 天前
Redis 持久化:RDB 快照与 AOF 日志
数据库·redis·mybatis
隔窗听雨眠2 天前
云数仓向PostgreSQL生态延伸的技术动因与工程代价
postgresql·数据库架构·云数仓
CoderYanger3 天前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第二弹)
java·数据库·spring boot·spring·面试·java-ee·mybatis
Peter-OK3 天前
PostgreSQL学习笔记(入门-进阶-精通说明)
笔记·学习·postgresql
Hello_Pyhx4 天前
NWinfo 导出 Windows 硬件信息:从 JSON 报告到缺项排查
windows·json
程序员大阳5 天前
副队长JavaScript教程(66)-本地存储实战:待办事项网页的开发
javascript·json·实战·待办事项·本地存储·案例
FungLeo5 天前
成为全栈·基础补充·数据库索引:为什么加了索引还是慢
mysql·postgresql·sqlite·sql优化·数据库索引·成为全栈
CoderYanger5 天前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)
java·数据库·spring·面试·职场和发展·java-ee·mybatis