MybatisPlus如何自定義TypeHandler對映JSON型別為List
阿新 • • 發佈:2022-01-23
目錄
- 自定義TypeHandler對映ON型別為List
- 1. 實體類
- 2. ListTypeHandler
- 3. ReportUserListTypeHandler
- 4. 泛型
- 自定義TypeHandler的使用筆記
- 型別轉換器還可以通過註解配置 java型別和jdbc型別
- 定義
- 使用
自定義TypeHandler對映JSON型別為List
1. 實體類
這裡只展示需要對映的欄位,分別在所需對映的欄位和實體類上添加註解。
@Data @TableName(value = "report",autoResultMap = true) public class Report { private static final long serialVersionUID = 1L; @ApiModelProperty("id") @TableId(value = "id",type = IdType.AUTO) private Integer id; @ApiModelProperty("報名資訊") @TableField(typeHandler = ReportUserListTypeHandler.class) private List<ReportUser> reportInfo; }
2. ListTypeHandler
提供一個 JSONArray 轉換為 Java List集合的處理器
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedJdbcTypes; import org.apache.ibatis.type.MappedTypes; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @MappedJdbcTypes(JdbcType.VARBINARY) @MappedTypes({List.class}) public abstract class ListTypeHandler<T> extends BaseTypeHandler<List<T>> { @Override public void setNonNullParameter(PreparedStatement ps,int i,List<T> parameter,JdbcType jdbcType) throws SQLException { String content = CollUtil.isEmpty(parameter) ? null : JSON.toJSONString(parameter); ps.setString(i,content); } @Override public List<T> getNullableResult(ResultSet rs,String columnName) throws SQLException { return this.getListByJsonArrayString(rs.getString(columnName)); } @Override public List<T> getNullableResult(ResultSet rs,int columnIndex) throws SQLException { return this.getListByJsonArrayString(rs.getString(columnIndex)); } @Override public List<T> getNullableResult(CallableStatement cs,int columnIndex) throws SQLException { return this.getListByJsonArrayString(cs.getString(columnIndex)); } private List<T> getListByJsonArrayString(String content) { return StrUtil.isBlank(content) ? new ArrayList<>() : JSON.parseObject(content,this.specificType()); } /** * 具體型別,由子類提供 * * @return 具體型別 */ protected abstract TypeReference<List<T>> specificType(); }
3. ReportUserListTypeHandler
由具體的子類提供List集合泛型型別
import com.alibaba.fastjson.TypeReference; import com.hanku.business.model.ReportUser; import java.util.List; public class ReportUserListTypeHandler extends ListTypeHandler<ReportUser> { @Override protected TypeReference<List<ReportUser>> specificType() { return new TypeReference<List<ReportUser>>() { }; } }
4. Java 泛型
如果在 ListTypeHandler 類中直接提供 TypeReference<List<T>> 這種型別,那就等效於TypeReference<List<Object>> 這種型別,後續 fastjson 在轉換時無法確定具體的 Java 型別,轉換後的型別最終就會是 List<JSONObject> ;同理,如果使用 Jackson 作為 JSON 轉換工具,不確定具體型別時,最總會被轉換為LinkedHashMap 型別,都需要再使用 TypeReference 來轉換一次。
自定義TypeHandler的使用筆記
可通過自定義的TypeHandler實現某個屬性在插入以及查詢時的自動轉換,本例中是要將Map型別的屬性轉化成CLOB,然後存入資料庫。由於是複雜的Map,mp自帶的json轉換器會丟失部分資訊。
型別轉換器還可以通過註解配置 java型別和jdbc型別
@MappedTypes
:註解配置 java 型別@MappedJdbcTypes
:註解配置 jdbc 型別
定義
@Slf4j @MappedTypes({Object.class}) @MappedJdbcTypes(JdbcType.VARCHAR) public class WeightListTypeHandler extends AbstractJsonTypeHandler<Object> { private static Gson gson = new Gson(); private final Class<?> type; public WeightListTypeHandler(Class<?> type) { if (log.isTraceEnabled()) { log.trace("WeightListTypeHandler(" + type + ")"); } Assert.notNull(type,"Type argument cannot be null"); this.type = type; } @Override protected Object parse(String json) { Type type1 = new TypeToken<Map<String,List<WeightItem>>>(){}.getType(); return gson.fromJson(json,type1); } @Override protected String toJson(Object obj) { return gson.toJson(obj); } public static void setGson(Gson gson) { Assert.notNull(gson,"Gson should not be null"); WeightListTypeHandler.gson = gson; } }
使用
注意@TableName 註解 autoResultMap 屬性
@Data @NoArgsConstructor @TableName(value = "mix_target",autoResultMap = true) public class MixTarget extends Model<MixTarget> { @TableId(value = "id",type = IdType.AUTO) private Long id; /** *指標描述 */ @TableField("description") private String descriphttp://www.cppcns.comtion; /** * 指標名 */ @TableField("name") private String name; /** * 對應屬性名 */ @TableField("property_name") private String propertyName; /** * 起始點型別 */ @TableField("source_type") private String sourceType; /** * 屬性對應權值列表 * key 屬性名 value指定條件下的權值 */ @TableField(value = "weight_list",typeHandler = WeightListTypeHandler.class,jdbcType = JdbcType.CLOB) private Map<String,List<WeightItem>> weightList; /** * 執行狀態 * 0 新建未執行 * 1 執行中 * 2 已執行 成功 * 3 已執行 失敗 http://www.cppcns.com */ @TableField("status") private Integer status; /** * 是否可用 * 1 true * 0 false */ @TableField("enable") private Integer enable; @TableField("create_time") private LocalDateTime createTime; }
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。