mybatisPlus 将List<String>字段转成json字符串,使用JacksonTypeHandler以及自定义类型处理器实现

文章目录

场景

项目中经常需要将List转成json存储到配置文件中, mybatisPlus默认实现了JacksonTypeHandler,GsonTypeHandler,FastjsonTypeHandler,也可以自定义类型处理器。

使用JacksonTypeHandler实现类型转换

  1. DO维护@TableName(value = "system_oauth2_access_token", autoResultMap = true), autoResultMap是需要显示设置的
  2. DO 指定字段维护@TableField(typeHandler = JacksonTypeHandler.class)
java 复制代码
@TableName(value = "system_oauth2_access_token", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
public class OAuth2AccessTokenDO extends BaseTenantDO {

    /**
     * 编号,数据库递增
     */
    @TableId
    private Long id;
    /**
     * 访问令牌
     */
    private String accessToken;
    /**
     * 刷新令牌
     */
    private String refreshToken;
    /**
     * 用户编号
     */
    private Long userId;
    /**
     * 用户类型
     *
     * 枚举 {@link UserTypeEnum}
     */
    private Integer userType;
    /**
     * 客户端编号
     tong
     * 关联 {@link OAuth2ClientDO#getId()}
     */
    private String clientId;
    /**
     * 授权范围
     */
//    @TableField(typeHandler = StringListTypeHandler.class)
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<String> scopes;
    /**
     * 过期时间
     */
    private LocalDateTime expiresTime;

}

使用JacksonTypeHandler插入没有问题, 但是在查询时报错argument type mismatch, 跟踪代码发现是在org.apache.ibatis.reflection.factory.DefaultObjectFactory.instantiateClass()函数报错, 反射构造函数的时候实际入参是String, 而构造函数的入参设置成List。此时还没有到JacksonTypeHandler String to List的解析代码。没有找到解决方案,猜测跟mybatisPlus或者springboot版本有关系,可以试试换个版本

自定义StringListTypeHandler处理器实现

  1. DO类维护 autoResultMap = true
  2. DO类指定字段 指定类处理器 @TableField(typeHandler = StringListTypeHandler.class)
java 复制代码
@TableName(value = "system_oauth2_access_token", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
public class OAuth2AccessTokenDO extends BaseTenantDO {

    /**
     * 编号,数据库递增
     */
    @TableId
    private Long id;
    /**
     * 访问令牌
     */
    private String accessToken;
    /**
     * 刷新令牌
     */
    private String refreshToken;
    /**
     * 用户编号
     */
    private Long userId;
    /**
     * 用户类型
     *
     * 枚举 {@link UserTypeEnum}
     */
    private Integer userType;
    /**
     * 客户端编号
     tong
     * 关联 {@link OAuth2ClientDO#getId()}
     */
    private String clientId;
    /**
     * 授权范围
     */
    @TableField(typeHandler = StringListTypeHandler.class)
//    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<String> scopes;
    /**
     * 过期时间
     */
    private LocalDateTime expiresTime;

}
  1. 定义List泛型转换器
java 复制代码
/**
 * @version V1.0
 * @author: carsonlius
 * @date: 2024/1/8 11:25
 * @company
 * @description List泛型处理器
 */

public abstract class ListTypeHandler<T> extends BaseTypeHandler<List<T>> {
    /**
     * 具体类型,由子类实现
     * @return 具体类型
     * */
    protected abstract Class<T> getType();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
        String context = CollectionUtils.isEmpty(parameter) ? null : JsonUtils.toJsonString(parameter);
        ps.setString(i, context);
    }

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

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

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

    /**
     * 根据json字符串格式化成List
     * */
    private List<T> getResult(String context) {
        return StrUtil.isBlank(context) ? new ArrayList<>() : JsonUtils.parseArray(context, getType());
    }
}
  1. 定义List子类
java 复制代码
/**
 * @version V1.0
 * @author: carsonlius
 * @date: 2024/1/8 13:57
 * @company
 * @description List<String>和Json之间的转化
 */
@MappedTypes(List.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class StringListTypeHandler extends ListTypeHandler<String> {
    @Override
    protected Class<String> getType() {
        return String.class;
    }
}
  1. 注册类型处理器

mybatis-plus.type-handlers-package 用于指定扫描包的路径,以注册自定义的类型处理器(Type Handlers)

java 复制代码
mybatis-plus.type-handlers-package: com.carsonlius.framework.mybatis.core.handler
相关推荐
毕设源码_钟学姐4 分钟前
计算机毕业设计springboot宿舍管理信息系统 基于Spring Boot的高校宿舍管理平台设计与实现 Spring Boot框架下的宿舍管理系统开发
spring boot·后端·课程设计
军军君0112 分钟前
基于Springboot+UniApp+Ai实现模拟面试小工具二:后端项目搭建
前端·javascript·spring boot·spring·微信小程序·前端框架·集成学习
全栈凯哥1 小时前
16.Spring Boot 国际化完全指南
java·spring boot·后端
后端小肥肠4 小时前
效率革命!10分钟用Dify+Spring Boot打造AI热点雷达,自媒体选赛道再不难!(附保姆级教程)
人工智能·spring boot·agent
Linn4 小时前
Spring WebSocket 服务实现的主流方案与最佳实践
spring boot·后端·spring
我是老孙5 小时前
Spring Boot 应用中,配置的加载优先级
spring boot·后端·pycharm
风象南5 小时前
基于 SpringBoot 的 REST API 与 RPC 调用的统一封装
java·spring boot·后端
weixin_456904277 小时前
Spring Boot整合MyBatis+MySQL+Redis单表CRUD教程
spring boot·mysql·mybatis
努力的小郑7 小时前
Spring事件监听器深度指南:3大企业级实战场景+避坑技巧,从原理到架构决策
java·spring boot
武昌库里写JAVA7 小时前
使用 Java 开发大数据应用:Hadoop 与 Java API 的结合
java·开发语言·spring boot·学习·课程设计