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 (一)
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。