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<List<Map<String, Object>>> {
|
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
private static final TypeReference<List<Object>> LIST_TYPE_REF = new TypeReference<List<Object>>() {};
|
|
/**
|
* 解析 JSON 字符串为 List<Map<String, Object>>
|
*/
|
private List<Map<String, Object>> parse(String json) {
|
if (json == null || json.trim().isEmpty()) {
|
return new ArrayList<>();
|
}
|
|
try {
|
// 先解析为 List<Object>
|
List<Object> rawList = OBJECT_MAPPER.readValue(json, LIST_TYPE_REF);
|
|
if (rawList == null || rawList.isEmpty()) {
|
return new ArrayList<>();
|
}
|
|
List<Map<String, Object>> 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<String, Object> map = (Map<String, Object>) item;
|
result.add(map);
|
} else if (item instanceof Number) {
|
// 纯ID数组格式 [1, 2, 3],转换为对象数组
|
Map<String, Object> 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<Map<String, Object>> 转换为 JSON 字符串
|
*/
|
private String toJson(List<Map<String, Object>> 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<Map<String, Object>> parameter, JdbcType jdbcType) throws SQLException {
|
ps.setString(i, toJson(parameter));
|
}
|
|
@Override
|
public List<Map<String, Object>> getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
String json = rs.getString(columnName);
|
return parse(json);
|
}
|
|
@Override
|
public List<Map<String, Object>> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
String json = rs.getString(columnIndex);
|
return parse(json);
|
}
|
|
@Override
|
public List<Map<String, Object>> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
String json = cs.getString(columnIndex);
|
return parse(json);
|
}
|
}
|