|
@@ -0,0 +1,68 @@
|
|
|
|
|
+package com.lingyue.common.mybatis;
|
|
|
|
|
+
|
|
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
|
|
+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 org.postgresql.util.PGobject;
|
|
|
|
|
+
|
|
|
|
|
+import java.sql.CallableStatement;
|
|
|
|
|
+import java.sql.PreparedStatement;
|
|
|
|
|
+import java.sql.ResultSet;
|
|
|
|
|
+import java.sql.SQLException;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * PostgreSQL JSONB 类型处理器
|
|
|
|
|
+ *
|
|
|
|
|
+ * 用于处理 PostgreSQL 的 JSONB 类型字段与 Java 对象之间的转换。
|
|
|
|
|
+ * 解决 MyBatis-Plus JacksonTypeHandler 无法正确处理 PostgreSQL JSONB 类型的问题。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author lingyue
|
|
|
|
|
+ * @since 2026-01-17
|
|
|
|
|
+ */
|
|
|
|
|
+@MappedTypes({Object.class})
|
|
|
|
|
+@MappedJdbcTypes(JdbcType.OTHER)
|
|
|
|
|
+public class PostgreSqlJsonbTypeHandler extends BaseTypeHandler<Object> {
|
|
|
|
|
+
|
|
|
|
|
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void setNonNullParameter(PreparedStatement ps, int i, Object 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 object to JSONB: " + e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ ps.setObject(i, pgObject);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
|
|
|
|
+ return parseJson(rs.getString(columnName));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
|
|
|
|
+ return parseJson(rs.getString(columnIndex));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
|
|
|
|
+ return parseJson(cs.getString(columnIndex));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private Object parseJson(String json) throws SQLException {
|
|
|
|
|
+ if (json == null || json.isEmpty()) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ return OBJECT_MAPPER.readValue(json, Object.class);
|
|
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
|
|
+ throw new SQLException("Error parsing JSONB: " + e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|