文章目录
- 场景
- 使用JacksonTypeHandler实现类型转换
- 自定义StringListTypeHandler处理器实现
场景
项目中经常需要将List转成json存储到配置文件中, mybatisPlus默认实现了JacksonTypeHandler,GsonTypeHandler,FastjsonTypeHandler,也可以自定义类型处理器。
使用JacksonTypeHandler实现类型转换
- DO维护@TableName(value = “system_oauth2_access_token”, autoResultMap = true), autoResultMap是需要显示设置的
- DO 指定字段维护@TableField(typeHandler = JacksonTypeHandler.class)
@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处理器实现
- DO类维护 autoResultMap = true
- DO类指定字段 指定类处理器 @TableField(typeHandler = StringListTypeHandler.class)
@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;
}
- 定义List泛型转换器
/**
* @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());
}
}
- 定义List子类
/**
* @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;
}
}
- 注册类型处理器
mybatis-plus.type-handlers-package 用于指定扫描包的路径,以注册自定义的类型处理器(Type Handlers)
mybatis-plus.type-handlers-package: com.carsonlius.framework.mybatis.core.handler