基于mybatis-typeHandler扩展 对象、对象集合以json的形式存取数据库

问题的诞生

有些业务场景下,数据库中字符串字段要存一个json,比方说:商品的展示图片集合、文档的附件集合之类的。

那么就会出现这种情况- -

@Data
@Accessors(chain = true)
public class ProductVO implements Serializable {
    private static final long serialVersionUID = 6421692337875809507L;

    /**
     * 展示图片
     */
    private List<String> images;


}
@Data
@Accessors(chain = true)
@TableName(value = "product")
public class ProductDO implements Serializable {
    private static final long serialVersionUID = 6421692337875809507L;

    /**
     * 展示图片[json]
     */
    private String images;


}

增加、更改、查询的时候都要手动去转换…感觉十分的麻烦!!!

问题的解决

解决环境

Spring Boot 2.3.2 MyBatis Plus 3.4.1

其实产生问题的原因就是:我们通过ORM操作数据库时,给他和拿到的东西数据类型不一致…
然后我就搜orm层能不能解决这个问题 - - 最后找到了…typeHandler就是解决这个问题的!!

代码如下

抽象的typeHandler类:

/**
 * @Author:cyw
 * @CreateTime: 2021/3/3 17:18
 **/
@MappedTypes(List.class)
@MappedJdbcTypes(value = {JdbcType.BLOB, JdbcType.VARCHAR, JdbcType.CHAR})
public abstract class ListJsonTypeHandler<T> extends BaseTypeHandler<List<T>> {


    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, serializer(parameter));
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String info = rs.getString(columnName);
        return deserializer(info);
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return deserializer(rs.getString(columnIndex));
    }

    @Override
    public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return deserializer(cs.getString(columnIndex));
    }

    private String serializer(List<T> parameter) {
        return JsonUtils.toJsonIfPresent(parameter);
    }

    protected List<T> deserializer(String info) {
        throw new BaseException("根据泛型类型 重写反序列化方法");
    }

}

子类指定泛型

/**
 * @Author:cyw
 * @CreateTime: 2021/3/3 20:58
 **/
public class ListString2JsonTypeHandler extends ListJsonTypeHandler<String> {

    @Override
    protected List<String> deserializer(String info) {
        return BaseUtils.isEmpty(info) ? Lists.newArrayList() : JsonUtils.toListIfPresent(info, String.class);
    }
}

如何要写个抽象的类

害… 还不是List泛型擦除导致的… 要是不清楚泛型擦除的各位,可以百度下
我们现在举例的场景是String类型,要是下次处理Long或者是自定义的对象,我们直接继承这个抽象typeHandler指定泛型,去重写反序列化方法就好了!!

代码整完之后,就要开始配置咯

指定上面类所在的包路径

mybatis:
  type-handlers-package: xxxxx

MP下使用

@Data
@Accessors(chain = true)
@TableName(value = "product", autoResultMap = true)
public class ProductDO implements Serializable {
    private static final long serialVersionUID = 6421692337875809507L;

    /**
     * 展示图片[json]
     */
    @TableField(typeHandler = ListString2JsonTypeHandler.class)
    private List<String> images;


}

注意了!
除了使用@TableField注解指定 所需的TypeHandler类
还要在@TableName注解里配置 autoResultMap 的属性

我这边举了MP的使用情况,mybatis的使情况也差不多…无非就是mp基于注解的形式 mybatis基于xml去指定,主要是我们去想清楚 这种通用的处理方法应该在哪一步…然后再去想办法去找解决方案去解决!!!拒绝无脑搬砖

相关代码

相关代码链接

其实这个项目是我常用的工具类,大家可以clone下来看看,有啥好的想法或者好用的工具类可以pr下或者留下评论!当然点个star最好啦 嘻嘻嘻嘻

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值