在 MyBatis-Flex 中处理 PostgreSQL 的数组类型字段(如 int[]
、varchar[]
),需通过自定义 TypeHandler
实现类型转换。以下是具体实现方案及注意事项:
一、核心问题与解决方案
MyBatis-Flex 未原生支持 PostgreSQL 数组类型,但可通过以下方式解决:
1.自定义 TypeHandler
继承 BaseTypeHandler
,将 Java 集合(如 List<String>
)与 PostgreSQL 的 ARRAY
类型互相转换。
示例代码:
package com.fuyo.framework_api.postgresql; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.*; import java.util.Arrays; import java.util.List; @Slf4j public class ArrayTypeHandler extends BaseTypeHandler<List<String>> { @Override public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException { Object[] objects = parameter.toArray(); Array array = ps.getConnection().createArrayOf("varchar", objects); ps.setArray(i, array); } @Override public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException { return getArray(rs.getArray(columnName)); } @Override public List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return getArray(rs.getArray(columnIndex)); } @Override public List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return getArray(cs.getArray(columnIndex)); } private List<String> getArray(Array array) { if (array == null) { return null; } try { String[] objects = (String[]) array.getArray(); return Arrays.asList(objects); } catch (SQLException e) { log.error("sql转换失败"); } return null; } }
配置实体类:
public class User { @Column(jdbcType = JdbcType.ARRAY,typeHandler = ArrayTypeHandler.class) private List<String> tags; }
2.SQL 操作符适配
使用 PostgreSQL 数组函数(如 @>
、ANY
)进行查询:
-- 查询包含特定值的数组字段 SELECT * FROM table WHERE array_field @> ARRAY['value']; -- 关联查询示例 SELECT * FROM table LEFT JOIN related_table ON related_table.id = ANY(array_field);
二、高级场景处理
1.动态 SQL 拼接
在 MyBatis-Flex 的 XML 中动态处理数组参数:
<select id="selectByArray" parameterType="map"> SELECT * FROM table WHERE array_field @> #{arrayParam, typeHandler=org.apache.ibatis.type postgreSQLArrayHandler} </select>
2.存储过程调用
调用含数组参数的存储过程时,需配置 statementType="CALLABLE"
并指定 TypeHandler
:
<select id="callproc" statementType="CALLABLE" resultType="void"> {call func_arr_update(#{ids, typeHandler= ArrayTypeHandler})} </select>
三、注意事项
- 类型一致性
PostgreSQL 数组类型需与 Java 类型严格匹配(如int[]
对应Integer[]
),否则可能抛出TypeException
。 - 性能优化
避免在复杂查询中频繁使用数组操作符,可结合array_agg
函数优化聚合查询。 - 版本兼容性
确保 MyBatis-Flex 版本(如 3.5.3+)兼容 PostgreSQL 驱动(如postgresql-42.x.x.jar
)。
四、总结
通过自定义 TypeHandler
和 SQL 操作符适配,MyBatis-Flex 可实现对 PostgreSQL 数组字段的完整支持。开发者需注意类型映射、动态 SQL 拼接及版本兼容性问题。若需进一步优化,可参考 PostgreSQL 的 array_agg
函数或调整存储过程调用逻辑。
参考: