仕事中に学ぶことは速いですが、さまざまな奇妙な要件が私に振りかかってきます。余計なことは言わずに、直接始めましょう。
既知の要件は、アンケートフォームを設計することで、現在のアンケートの質問タイプは単一選択肢のみで、テーブルとデータベースの設計方法についてです。
問題テーブルは以下のようになります。
疼痛分類 | 説明 | スコア |
---|---|---|
0 | 無痛 | 0 |
1 | 微痛 | 2 |
2 | 剧痛 | 4 |
1 つの問題には複数の選択肢があり、それぞれの選択肢には異なるスコアがあります。これは最終的なアンケートのスコアを計算するために使用されます。
単一のテーブルを作成すると非常に複雑で、ロジックが明確ではないため、問題を抽出することができます。
オプションテーブル
/**
* オプションの説明
*/
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 Handle#
良いニュースは、mybatis-plus がデータベースとコードの間のデータフローを処理するためのカスタムタイプハンドラを提供していることです。
typeHandle を使用するには、設定ファイルで次のように設定する必要があります。
# カスタムタイプハンドラのパッケージパスを設定します
mybatis-plus.type-handlers-package=xyz.qinfengge.handel
そして、ハンドラクラスを設定します。
@MappedTypes({OptionDto.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
public class OptionsTypeHandle 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 () をデータベースに保存します。次の 3 つのメソッドはクエリ文で、JSON をオブジェクトに変換する必要があります。書かない場合は null になります。
最後に、エンティティクラスで使用するカスタムデータ型のタイプハンドラを指定します。
//アンケートID
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
//問題名
private String name;
private Integer typeId;
//オプション1、オプションテーブルに対応
//タイプハンドラを指定します
@TableField(typeHandler = OptionsTypeHandle.class)
private OptionDto op1;
これで完了です。