|
@@ -0,0 +1,72 @@
|
|
|
|
|
+package com.lingyue.document.mybatis;
|
|
|
|
|
+
|
|
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
|
|
+import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
+import com.lingyue.document.entity.DocumentBlock.TextElement;
|
|
|
|
|
+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 org.postgresql.util.PGobject;
|
|
|
|
|
+
|
|
|
|
|
+import java.sql.CallableStatement;
|
|
|
|
|
+import java.sql.PreparedStatement;
|
|
|
|
|
+import java.sql.ResultSet;
|
|
|
|
|
+import java.sql.SQLException;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * TextElement 列表类型处理器
|
|
|
|
|
+ *
|
|
|
|
|
+ * 专门处理 DocumentBlock.elements 字段的序列化和反序列化。
|
|
|
|
|
+ * 解决通用 PostgreSqlJsonbTypeHandler 无法正确反序列化泛型类型的问题。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author lingyue
|
|
|
|
|
+ * @since 2026-01-28
|
|
|
|
|
+ */
|
|
|
|
|
+@MappedTypes({List.class})
|
|
|
|
|
+@MappedJdbcTypes(JdbcType.OTHER)
|
|
|
|
|
+public class TextElementListTypeHandler extends BaseTypeHandler<List<TextElement>> {
|
|
|
|
|
+
|
|
|
|
|
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
|
|
|
|
+ private static final TypeReference<List<TextElement>> TYPE_REF = new TypeReference<>() {};
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void setNonNullParameter(PreparedStatement ps, int i, List<TextElement> parameter, JdbcType jdbcType) throws SQLException {
|
|
|
|
|
+ PGobject pgObject = new PGobject();
|
|
|
|
|
+ pgObject.setType("jsonb");
|
|
|
|
|
+ try {
|
|
|
|
|
+ pgObject.setValue(OBJECT_MAPPER.writeValueAsString(parameter));
|
|
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
|
|
+ throw new SQLException("Error converting List<TextElement> to JSONB: " + e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ ps.setObject(i, pgObject);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<TextElement> getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
|
|
|
|
+ return parseJson(rs.getString(columnName));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<TextElement> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
|
|
|
|
+ return parseJson(rs.getString(columnIndex));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<TextElement> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
|
|
|
|
+ return parseJson(cs.getString(columnIndex));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private List<TextElement> parseJson(String json) throws SQLException {
|
|
|
|
|
+ if (json == null || json.isEmpty()) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ return OBJECT_MAPPER.readValue(json, TYPE_REF);
|
|
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
|
|
+ throw new SQLException("Error parsing JSONB to List<TextElement>: " + e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|