qinfengge

qinfengge

醉后不知天在水,满船清梦压星河
github

mybatis-plus配置自定义数据类型

上班学习就是快,各种奇怪的需求提的我眼花缭乱。废话不多说,直接开搞

已知需求是设计一张问卷表,目前问卷的问题类型只有单选题,怎么设计表和库。

问题表类似下面

疼痛分级描述分数
0无痛0
1微痛2
2剧痛4

一个问题下面有多个选项,每个选项有不同的分值,用于最后计算问卷的最终得分。

如果建单表,会非常复杂而且逻辑不清晰,不如把问题抽出来

选项表

/**
     * 选项的描述
     */
    private String description;
    /**
     * 选项的分数
     */
    private Integer score;

然后在数据库直接保存 json,日后扩展也简单了。

那么怎么保存 json 到数据库呢?

问卷表

	//问卷ID
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    //问题名称
    private String name;

    private Integer typeId;
    //选项1,对应选项表
    private OptionDto op1;

很简单,直接 fast json 一把梭,重写问卷表的特定字段的 set 方法即可

 public void setOp1(OptionDto dto) {
     //将OptionDto对象转换为JSON字符串
        this.op1 = JSON.toJSONString(dto);
    }

这样就能将 OptionDto 转为 json 存到数据库了。

但是,当我从数据库取数据时,会发现 OptionDto 数据变为 null 了,明明查询语句是没问题的,SQL 也能查出来,但是就是赋不了值。

这是因为 mybatis-plus 无法处理我们自定义的数据类型,我们数据库是 VARCHAR,但是代码里却不是 String,所以赋不了值。

Type Hnadel#

好消息是,mybatis-plus 提供了自定义的类型处理类,来处理代码和数据库之间的数据流转,就是 TypeHandle

要使用 typeHandel,需要在配置文件配置

# 配置自定义类型转换器的包路径
mybatis-plus.type-handlers-package=xyz.qinfengge.handel

然后配置处理类

@MappedTypes({OptionDto.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
public class OptionsTypeHandel extends BaseTypeHandler<OptionDto> {
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, OptionDto optionDto, JdbcType jdbcType) throws SQLException {
        preparedStatement.setString(i, optionDto.toString());
    }

    @Override
    public OptionDto getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return resultSet.getString(s) == null ? null : str2Dto(resultSet.getString(s));
    }

    @Override
    public OptionDto getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return resultSet.getString(i) == null ? null : str2Dto(resultSet.getString(i));
    }

    @Override
    public OptionDto getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return callableStatement.getString(i) == null ? null : str2Dto(callableStatement.getString(i));
    }

    //把String转为OptionDto
    public static OptionDto str2Dto(String string) {
        //将JSON字符串转换为OptionDto对象
        return JSON.parseObject(string, OptionDto.class);
    }
}
  • @MappedTypes中填写的是我们代码中的数据类型
  • @MappedJdbcTypes中填写的是数据库中的数据类型

重写里面的 4 个方法,第一个方法是保存数据,所以直接 optionDto.toString () 保存到数据库,下面三个方法是查询语句,要把 json 转为对象,如果不写,就是 null。

最后指定实体类中自定义数据类型使用的类型解析器

	//问卷ID
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    //问题名称
    private String name;

    private Integer typeId;
    //选项1,对应选项表
    //指定类型解析器
    @TableField(typeHandler = OptionsTypeHandel.class)
    private OptionDto op1;

这样就 OK 了。

  1. mybatis-plus 如何配置自定义数据类型 TypeHandle
  2. MyBatis TypeHandler 学习及实战
  3. Mybatis 优雅存取 json 字段的解决方案 - TypeHandler (一)
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。