在 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 函数或调整存储过程调用逻辑。
参考: