package com.vincent.rsf.server.manager.utils; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; 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.HashMap; import java.util.List; import java.util.Map; /** * @author chen.lin * @time 2026-02-02 * Areas 字段自定义 TypeHandler * 处理数据库和 Java 对象之间的转换 * 支持两种格式: * 1. [1, 2, 3] - 纯ID数组(向后兼容) * 2. [{"id": 1, "sort": 1}, {"id": 2, "sort": 2}] - 对象数组(新格式) * */ @MappedTypes({List.class}) @MappedJdbcTypes(JdbcType.VARCHAR) public class AreasTypeHandler extends BaseTypeHandler>> { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final TypeReference> LIST_TYPE_REF = new TypeReference>() {}; /** * 解析 JSON 字符串为 List> */ private List> parse(String json) { if (json == null || json.trim().isEmpty()) { return new ArrayList<>(); } try { // 先解析为 List List rawList = OBJECT_MAPPER.readValue(json, LIST_TYPE_REF); if (rawList == null || rawList.isEmpty()) { return new ArrayList<>(); } List> result = new ArrayList<>(); // 遍历所有元素并转换 for (int i = 0; i < rawList.size(); i++) { Object item = rawList.get(i); if (item instanceof Map) { // 已经是对象数组格式 [{"id": 1, "sort": 1}] @SuppressWarnings("unchecked") Map map = (Map) item; result.add(map); } else if (item instanceof Number) { // 纯ID数组格式 [1, 2, 3],转换为对象数组 Map area = new HashMap<>(); area.put("id", ((Number) item).intValue()); area.put("sort", i + 1); result.add(area); } // 忽略其他类型 } return result; } catch (Exception e) { throw new RuntimeException("Failed to parse areas JSON: " + json, e); } } /** * 将 List> 转换为 JSON 字符串 */ private String toJson(List> obj) { if (obj == null) { return null; } try { return OBJECT_MAPPER.writeValueAsString(obj); } catch (Exception e) { throw new RuntimeException("Failed to serialize areas to JSON", e); } } @Override public void setNonNullParameter(PreparedStatement ps, int i, List> parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, toJson(parameter)); } @Override public List> getNullableResult(ResultSet rs, String columnName) throws SQLException { String json = rs.getString(columnName); return parse(json); } @Override public List> getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String json = rs.getString(columnIndex); return parse(json); } @Override public List> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String json = cs.getString(columnIndex); return parse(json); } }