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
相关推荐
Jabes.yang1 小时前
Java面试场景:从Spring Web到Kafka的音视频应用挑战
大数据·spring boot·kafka·spring security·java面试·spring webflux
程序员小凯4 小时前
Spring Boot性能优化详解
spring boot·后端·性能优化
tuine4 小时前
SpringBoot使用LocalDate接收参数解析问题
java·spring boot·后端
番茄Salad5 小时前
Spring Boot项目中Maven引入依赖常见报错问题解决
spring boot·后端·maven
摇滚侠6 小时前
Spring Boot 3零基础教程,yml配置文件,笔记13
spring boot·redis·笔记
!if6 小时前
springboot mybatisplus 配置SQL日志,但是没有日志输出
spring boot·sql·mybatis
阿挥的编程日记7 小时前
基于SpringBoot的影评管理系统
java·spring boot·后端
java坤坤7 小时前
Spring Boot 集成 SpringDoc OpenAPI(Swagger)实战:从配置到接口文档落地
java·spring boot·后端
摇滚侠8 小时前
Spring Boot 3零基础教程,整合Redis,笔记12
spring boot·redis·笔记
荣淘淘8 小时前
互联网大厂Java求职面试全景实战解析(涵盖Spring Boot、微服务及云原生技术)
java·spring boot·redis·jwt·cloud native·microservices·interview