Java 使用JOOQ从表生成枚举类

Java 使用JOOQ从表生成枚举类,java,mysql,enums,jooq,Java,Mysql,Enums,Jooq,我有一个名为YNM的下表: id名称 1是的 2号 3也许 并希望JOOQ生成以下java枚举: 公共枚举YNM{ 是的,不,也许; } 我知道JOOQ 3中对这一点的支持因为过于复杂/违反直觉而被放弃。有没有办法做到这一点 提前感谢。我认为您应该能够使用枚举转换器 public class YNMConverter extends EnumConverter<String, YNM > { public YNMConverter() { super(S

我有一个名为YNM的下表:

id名称
1是的
2号
3也许
并希望JOOQ生成以下java枚举:

公共枚举YNM{
是的,不,也许;
}
我知道JOOQ 3中对这一点的支持因为过于复杂/违反直觉而被放弃。有没有办法做到这一点


提前感谢。

我认为您应该能够使用
枚举转换器

public class YNMConverter extends EnumConverter<String, YNM > {

    public YNMConverter() {
        super(String.class, YNM.class);
    }
}

您需要将强制类型和自定义类型添加到codegen。这可以通过maven/xml或编程方式完成

当然,您可以通过以下几个步骤重新实现已删除的功能:

1.实现该枚举的生成器 您需要重写
JavaGenerator
,以实现将主数据(可能是多个表)转换为枚举的代码生成。这完全取决于您,例如,您可以:

  • 单列主数据表
  • ID/值映射表
  • ID/值/注释映射表
  • 其他布局
2.为这些枚举生成
ForcedType
配置 每当引用此类主数据表时,应使用
配置将外键列重新连接到该枚举,因为这将允许您对jOOQ代码生成配置进行更动态的控制

3.防止生成主数据表 除上述内容外,您可能还应该从生成的输出中删除主数据表本身。在您的情况下,这将导致配置:

<excludes>YNM</excludes>
YNM
或者,如果您有多个主数据表:

<excludes>YNM|OTHER_MASTER_DATA_TABLE|...</excludes>
YNM |其他|主数据|表|。。。

排除这些表将阻止从jOOQ客户机代码访问它们,并删除生成代码中的外键信息,这可能会让人困惑。

我知道这是一个老问题,但我将公布我的答案,因为它可能对其他人有用

我必须面对同样的需求,而且很难实现,因此在这里您可以找到我实现的代码,用于从
enums
模式生成enum

代码是在groovy中实现的,但是对于java来说,它非常相似

首先,也是非常重要的,我必须为我的枚举生成器创建一个单独的项目,因为它将作为将要使用它的项目的依赖项。这是必需的,因为生成代码的项目必须在编译时运行枚举生成器,因此实现这一点的方法是将枚举生成器作为依赖项添加

枚举生成器项目依赖项 具有枚举表的数据库 将转换为枚举的表如下所示:

--表名'account\u role'将转换为'AccountRole'`
创建表enums.account\u角色(
“name”varchar(100)不为空,
说明varchar(255)不为空,
约束帐户\角色\名称\密钥唯一(名称)
);
--表项将转换为枚举项
在enums.account_角色(“名称”,描述)值中插入
(“账单”,“作为账单联系人/地址的联系人/地址的角色”),
(“付款”,“将作为付款联系人/地址的联系人/地址的角色”),
(“服务”,“联系人/地址的角色,将成为服务联系人/地址”),
('sell_TO','Role for contact/address,该联系人/地址将成为SoldTo contact/address')
;
此数据定义将导致以下自动生成的enum AccountRole.java:

/*
*该文件由jOOQ生成。
*/
包com.congerotechnology.ctgcommon.jooq.enums;
公共枚举帐户角色{
计费(“将成为计费联系人/地址的联系人/地址的角色”),
付款(“将成为付款联系人/地址的联系人/地址的角色”),
服务(“将成为服务联系人/地址的联系人/地址的角色”),
销售对象(“联系人/地址的角色,将成为SoldTo联系人/地址”);
私有最终字符串描述;
私有帐户角色(字符串描述){
this.description=描述;
}
}

主要项目 然后,在将要使用此枚举生成器的主项目上,我在
pom.xml
上设置了以下maven代码:


...
com.ctg
ctg jooq发电机
0.0.1
...
...
org.jooq
jooq codegen maven
${jooq.version}
生成源
生成源
生成
org.postgresql.Driver
jdbc:postgresql://${env.DB_URL}
${env.DB_USER}
${env.DB_PASSWORD}
com.ctg.ctgjooqgenerator.jooq.EnumGenerator
org.jooq.meta.postgres.PostgresDatabase
.*
真的
枚举
假的
真的
com.ctg.ctgcommon.jooq.enums
目标/生成源/jooq postgres
org.postgresql
postgresql
${postgresql.version}

您能举个简单的例子说明
YNM
表/行的枚举生成器是什么样子的吗?我的生成器
扩展了JavaGenerator
,但不确定挂接到哪里。两个问题:1)如何从我的生成器中选择表中的数据<代码>爪哇属
<excludes>YNM|OTHER_MASTER_DATA_TABLE|...</excludes>
package com.ctg.jooqgenerator.jooq

import org.jooq.codegen.JavaGenerator
import org.jooq.codegen.JavaWriter
import org.jooq.meta.Database
import org.jooq.meta.SchemaDefinition
import org.jooq.meta.TableDefinition
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import java.sql.ResultSet

class EnumGenerator extends JavaGenerator {
    private static final String ENUMS_SCHEMA = "enums"

    private static final Logger log = LoggerFactory.getLogger(EnumGenerator.class)

    @Override
    void generateSchema(SchemaDefinition schema) {
        // Apply custom logic only for `enums` schema. Others schema has regular generation
        if (schema.name != ENUMS_SCHEMA) {
            super.generateSchema(schema)
            return
        }

        log.info("Generating enums")
        log.info("----------------------------------------------------------")

        Database db = schema.database

        db.getTables(schema).each { TableDefinition table ->
            // Prepare enum name from snake_case to CamelCase
            String enumName = table.name.replaceAll('_([a-z])') { it[1].capitalize() }.capitalize()

            JavaWriter out = newJavaWriter(new File(getFile(schema).getParentFile(), "${enumName}.java"))
            log.info("Generating enum: {}.java [input={}, output={}]", enumName, table.name, enumName)

            printPackage(out, schema)

            out.println("public enum $enumName {")

            ResultSet rs = db.connection.prepareStatement("SELECT * FROM ${schema}.\"${table.name}\"").executeQuery()
            while (rs.next()) {
                String name = rs.getString('name'),
                       description = rs.getString('description'),
                       s = rs.isLast() ? ";" : ","

                // Generate enum entry
                out.tab(1).println("$name(\"$description\")$s")
            }

            out.println("""
            |    private final String description;
            |
            |    private $enumName(String description) {
            |        this.description = description;
            |    }
            |}
            """.stripMargin())

            closeJavaWriter(out)
        }

        log.info("----------------------------------------------------------")
        super.generateSchema(schema)
    }
}