Java 如何在数据库中存储枚举类名和枚举值

Java 如何在数据库中存储枚举类名和枚举值,java,mysql,jooq,Java,Mysql,Jooq,我有一个具有不同枚举的类,例如: class EligibilityRule{ ProductEligibility productEligibility; CountryEligibility countryEligibility } enum ProductEligibility{ PRODUCT_X, PRODUCT_Y } enum CountryEligibility{ US, IN, CN .. } 我想将这些不同的枚举类名及其值存储到名为合格规则的数据库表中,我的表模式如下所

我有一个具有不同枚举的类,例如:

class EligibilityRule{
ProductEligibility productEligibility;
CountryEligibility countryEligibility
}

enum ProductEligibility{
PRODUCT_X,
PRODUCT_Y
}

enum CountryEligibility{
US,
IN,
CN
..
}
我想将这些不同的枚举类名及其值存储到名为
合格规则的数据库表中,我的表模式如下所示

String id  => auto_increment id
String ruleType => enum class name (ex: ProductEligibility)
String ruleValue => enum value (ex: PRODUCT_X)
我使用的是JOOQ,过去我使用强制类型来存储枚举值。但是,在本例中,我希望存储枚举类名和枚举值。当我从db查询记录时,我还想重建enum对象

JOOQ中是否有我可以遵循的模式,或者是否有我可以扩展的功能来解决这个问题?

JOOQ支持。这意味着您可以为数据库字段定义一个
转换器
,然后在加载时自动映射到自定义类型。数据库字段仍将是一个
字符串
,但为该字段生成的
记录将包含一个
字段
。这意味着您不必显式存储类名

为此,必须在代码生成器中注册转换器(取自上述文档页面):

规则
为:

interface Rule { String getRuleType(); String getRuleValue(); }
然后在文档页面或单独链接的答案中创建一个转换器,如示例所示

当然,这也意味着
记录
s中会有一个
字段
字段,而不是枚举的特定类型。如果这对您来说是可以接受的,那么这可能是一种可行的方式


我没有得到这部分,
当然,这也意味着您的记录中会有一个字段,而不是枚举的特定类型。
。这是否意味着我仍将使用CustomConverter在db中为每个字段存储两个字段:rule_type和rule_value

不需要。您仍然只有一个转换器,类型为
converter
。此转换器将返回产品合格性
国家合格性
,但不能同时返回这两个

因此,如果您的数据库表有如下内容:

eligiblity_rules
------------------
id    user    type                              value 
234   223     com.foo.bar.ProductEligibility    PRODUCT_Y
856   855     com.foo.bar.CountryEligibility    US
您的转换器将如下所示:

public Converter<Object, Rule> converter() {
    return new Converter<Object, Rule>() {
        @Override
        public Rule from(Object t) {
            // t here refers to the "value" db field above
            if (checkIsProductEligibilityRule())
                 return ProductEligibility.fromValue(...);
            else
                return CountryEligibility.fromValue(...)
        }

        // Other converter methods
    };
}
之后,如果要使用特定的规则类型,则需要进行检查和强制转换:

if (rule instanceof ProductEligibility) {
    ProductEligibility peRule = (ProductEligibility) rule; 
    ...
}
if (rule instanceof CountryEligibility) {
    CountryEligibility ceRule = (CountryEligibility) rule;
    ...
}
...
创建
类型
数据库字段的唯一原因是选择正确的数据。不幸的是,Java代码不知道(在编译时)该字段的类型是什么,因此每次您希望知道该字段的特定类型时,都需要在运行时进行类检查。

JOOQ支持。这意味着您可以为数据库字段定义一个
转换器
,然后在加载时自动映射到自定义类型。数据库字段仍将是一个
字符串
,但为该字段生成的
记录将包含一个
字段
。这意味着您不必显式存储类名

为此,必须在代码生成器中注册转换器(取自上述文档页面):

规则
为:

interface Rule { String getRuleType(); String getRuleValue(); }
然后在文档页面或单独链接的答案中创建一个转换器,如示例所示

当然,这也意味着
记录
s中会有一个
字段
字段,而不是枚举的特定类型。如果这对您来说是可以接受的,那么这可能是一种可行的方式


我没有得到这部分,
当然,这也意味着您的记录中会有一个字段,而不是枚举的特定类型。
。这是否意味着我仍将使用CustomConverter在db中为每个字段存储两个字段:rule_type和rule_value

不需要。您仍然只有一个转换器,类型为
converter
。此转换器将返回产品合格性
国家合格性
,但不能同时返回这两个

因此,如果您的数据库表有如下内容:

eligiblity_rules
------------------
id    user    type                              value 
234   223     com.foo.bar.ProductEligibility    PRODUCT_Y
856   855     com.foo.bar.CountryEligibility    US
您的转换器将如下所示:

public Converter<Object, Rule> converter() {
    return new Converter<Object, Rule>() {
        @Override
        public Rule from(Object t) {
            // t here refers to the "value" db field above
            if (checkIsProductEligibilityRule())
                 return ProductEligibility.fromValue(...);
            else
                return CountryEligibility.fromValue(...)
        }

        // Other converter methods
    };
}
之后,如果要使用特定的规则类型,则需要进行检查和强制转换:

if (rule instanceof ProductEligibility) {
    ProductEligibility peRule = (ProductEligibility) rule; 
    ...
}
if (rule instanceof CountryEligibility) {
    CountryEligibility ceRule = (CountryEligibility) rule;
    ...
}
...

创建
类型
数据库字段的唯一原因是选择正确的数据。不幸的是,Java代码不知道(在编译时)该类型将是什么,因此每次您希望知道该字段的特定类型时,都需要在运行时进行类检查。

将来可能会有多个枚举类型具有相同的枚举值,所以我想显式存储枚举类名。只要不同的枚举类型映射到不同的数据库字段,具有相同值的多个枚举类型就可以了。您仍然不需要存储类名。我明白您的意思,在我的情况下,我不是为每个枚举创建新的数据库字段,而是将它们存储为规则类型和规则值(键/值)对,其中键是类名,值是枚举值。我已经用一个可能的解决方案更新了上面的答案。让我知道它是否适合你!我已经更新了上面的答案。这可以解释问题吗?将来可能会有多个枚举类型具有相同的枚举值,因此我希望显式存储枚举类名。只要不同的枚举类型映射到不同的数据库字段,具有相同值的多个枚举类型就可以了。您仍然不需要存储类名。我明白您的意思,在我的情况下,我不是为每个枚举创建新的数据库字段,而是将它们存储为规则类型和规则值(键/值)对,其中键是类名,值是枚举值。我已经用一个可能的解决方案更新了上面的答案。让我知道它是否适合你!我已经更新了上面的答案。这能解释事情吗?