有没有一种正确的方法可以使用 JOOQ 为所有方言创建一个包含枚举的表?

Posted

技术标签:

【中文标题】有没有一种正确的方法可以使用 JOOQ 为所有方言创建一个包含枚举的表?【英文标题】:Is there a proper way how to create a table with enums for all dialects with JOOQ? 【发布时间】:2020-05-04 07:49:17 【问题描述】:

我创建了一个由 Flyway 执行的 JOOQ 脚本,以创建一个带有一个枚举的表。当方案生成到运行的 PostgresSQL 实例中时,生成的 POJOS 枚举信息会丢失,并且该字段只是一个字符串。

sl.alterTable("tableName").addColumn("column", SQLDataType.VARCHAR.asEnumDataType(MyEnum.class)).execute();

// ...

enum MyEnum implements EnumType 
    A("A"),
    B("B");

    private final String literal;

    MyEnum(String literal) 
        this.literal = literal;
    

    @Override
    public String getLiteral() 
        return literal;
    

    @Override
    public String getName() 
        return V2020_01_09__table_constant.State.class.getName().toLowerCase();
    

要从 PostgresSQL 数据库生成枚举到 Java,我需要执行以下 hack 并区分 DB 方言。所以我需要为每一次迁移以一种特殊的方式处理枚举。

if (dsl.dialect().equals(SQLDialect.POSTGRES)) 
    dsl.createType("MyEnum").asEnum("a", "b").execute();
    dsl.alterTable("tableName").addColumn("column", new DefaultDataType<>(null, MyEnum.class, "myenum")).execute();
 else 
    dsl.alterTable("tableName").addColumn("column", SQLDataType.VARCHAR.asEnumDataType(MyEnum.class)).execute();

最后,我更换了支持枚举的 H2,一切看起来都很好。我在 Java POJOS 中有枚举。但是可能在 PostgresSQL 上运行的生产数据库仍然获得 varchars 类型。

有没有一种方法可以生成带有枚举的 PostgresSQL 架构,而不会隐含地说创建我的枚举类型?

【问题讨论】:

【参考方案1】:

最后,我更换了支持枚举的 H2,一切看起来都很好。我在 Java POJOS 中有枚举。

我上次检查时,H2 的枚举实现仍然缺少很多东西,我们还不能正确地对它们的枚举进行逆向工程,所以效果不好。

有没有一种方法可以使用枚举生成 PostgresSQL 架构而不隐含地说创建我的枚举类型?

如果您连接到一个实际的数据库实例来生成代码,那么在 PostgreSQL 中使用枚举应该不会有任何问题。如果您要使用供应商特定的数据类型(如枚举、数组等),我建议从等式中删除 H2。使用 H2 只会一直造成痛苦。我假设您正在使用 H2 进行集成测试。我建议将testcontainers 与实际的 PostgreSQL 数据库一起使用。

【讨论】:

以上是关于有没有一种正确的方法可以使用 JOOQ 为所有方言创建一个包含枚举的表?的主要内容,如果未能解决你的问题,请参考以下文章

未从 application.properties 中提取 Spring Boot JOOQ sql 方言

JOOQ 使用转换器将字符串转换为枚举

JOOQ 插入到具有大量记录的选择中

是否有一个 jOOQ 工具来验证生成的定义是否仍然正确?

如何查看 jOOQ 在编译时执行的 SQL 语句?

使用 jOOQ 使用正确的类型转换从 values() 中选择插入