You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用jOOQ时为PostgreSQL ARRAY列生成List类型

让jOOQ将PostgreSQL ARRAY列生成为List类型的方法

当然可以,有两种常用方式实现这个需求:

1. 自定义数据类型绑定(推荐用于代码生成阶段修改字段类型)

这种方式能直接让jOOQ生成的实体类字段类型变成List<String>,步骤如下:

  • 先实现一个Binding接口,负责数据库数组类型和Java List的双向转换:
public class StringArrayToListBinding implements Binding<Object[], List<String>> {

    @Override
    public void get(BindingGetResultSetContext<List<String>> ctx) throws SQLException {
        String[] dbArray = ctx.resultSet().getArray(ctx.index()).getArray(String[].class);
        ctx.convert(converter()).value(dbArray != null ? Arrays.asList(dbArray) : null);
    }

    @Override
    public void set(BindingSetStatementContext<List<String>> ctx) throws SQLException {
        List<String> list = ctx.value();
        String[] array = list != null ? list.toArray(new String[0]) : null;
        ctx.statement().setArray(ctx.index(), ctx.connection().createArrayOf("varchar", array));
    }

    @Override
    public Converter<Object[], List<String>> converter() {
        return new Converter<>() {
            @Override
            public List<String> from(Object[] dbArray) {
                return dbArray != null ? Arrays.asList(dbArray) : null;
            }

            @Override
            public Object[] to(List<String> list) {
                return list != null ? list.toArray(new String[0]) : null;
            }

            @Override
            public Class<Object[]> fromType() {
                return Object[].class;
            }

            @Override
            public Class<List<String>> toType() {
                return List.class;
            }
        };
    }

    // 实现其他Binding接口的默认方法(如register、sql等,可直接用默认实现)
}
  • 然后在jOOQ的代码生成配置里指定这个绑定,让它作用到所有varchar[]列:
<database>
    <customTypes>
        <customType>
            <name>java.util.List&lt;String&gt;</name>
            <type>java.util.List</type>
            <binding>com.your.package.StringArrayToListBinding</binding>
        </customType>
    </customTypes>
    <forcedTypes>
        <forcedType>
            <name>java.util.List&lt;String&gt;</name>
            <includeTypes>VARCHAR\\[\\]</includeTypes> <!-- 精确匹配varchar数组类型 -->
            <!-- 如果要匹配所有数组类型,改成<includeTypes>.*ARRAY</includeTypes> -->
        </forcedType>
    </forcedTypes>
</database>

重新生成代码后,实体类里对应的ARRAY列就会变成List<String>类型。

2. 运行时全局转换器(适合不想修改代码生成配置的场景)

如果只是希望在查询结果里自动把数组转成List,不需要修改生成的实体类字段类型,可以用jOOQ 3.15+提供的全局转换器配置:

DSLContext dsl = DSL.using(
    yourPostgresConnection,
    SQLDialect.POSTGRES,
    new Settings()
        .withConverterProvider(new DefaultConverterProvider() {
            @Override
            public <T, U> Converter<T, U> provide(Class<T> fromType, Class<U> toType) {
                if (fromType == String[].class && toType == List.class) {
                    return (Converter<T, U>) new Converter<>() {
                        @Override
                        public List<String> from(String[] array) {
                            return array != null ? Arrays.asList(array) : null;
                        }

                        @Override
                        public String[] to(List<String> list) {
                            return list != null ? list.toArray(new String[0]) : null;
                        }

                        @Override
                        public Class<String[]> fromType() {
                            return String[].class;
                        }

                        @Override
                        public Class<List<String>> toType() {
                            return List.class;
                        }
                    };
                }
                return super.provide(fromType, toType);
            }
        })
);

这种方式下,用这个DSLContext查询得到的结果里,数组类型会自动转为List,但生成的实体类字段依然是String[]。

内容的提问来源于stack exchange,提问作者dtech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:55:20