记住枚举或数据库表的国际化常量的最佳存储方式

时间:2018-08-10 22:28:15

标签: java database enums internationalization constants

我要存储大量静态/常量数据,这些数据也彼此相关。我可以使用很多枚举,互相引用形成一棵树或一张图。或者只是使用表或数据库枚举并在其中存储值,然后创建相应的类和各自的关系。我拥有的数据是恒定的,并且肯定不会改变。我可能还必须考虑在不久的将来进行国际化。我将使用此常量数据作为其他各种数据的过滤器。

我很想使用枚举,因为默认情况下它使我具有不变性,但是看到数据之间关系的复杂性,就像我可能不得不牺牲继承一样,我对枚举也不甚了解。从数据库和国际化中填充这些枚举类可能有些棘手。在以后的阶段中,希望它能够轻松扩展并包含复杂性是我关注的领域,因为我不想从中途退缩。!

---更新---

我还没有看到相互关联(关联)的枚举的示例,其中包含引用其他枚举的复杂类型的字段。在这种情况下,当数据恒定时,枚举可以替换类。 有什么客观的方法可以解决这个问题。

为了更好地理解,我有如下类似的分类。 Animal Kingdom having tree hierarchy

2 个答案:

答案 0 :(得分:1)

根据经验,仅当值的更改速度可能快于代码发布周期,并且当不是我的某个人可能更改它们时,我才涉及数据库。使代码依赖于正在运行(且可用)的数据库意味着,当某些DBA关闭数据库进行维护时,您的应用程序将无法启动。

答案 1 :(得分:1)

尽管这个问题对于Stack Overflow而言可能太宽泛了,但有一些想法。

枚举

您可能不完全了解Java中的枚举功能。请参阅Oracle TutorialEnum类文档。

枚举类,是常规Java类,是Enum的子类。唯一的特别之处是语法糖可以自动实例化您定义和命名的静态实例。否则,它们是普通课程:

  • 您的枚举可以带有成员变量。
  • 您的枚举可以具有构造函数,您可以将参数传递给那些构造函数。
  • 您的枚举可以提供其他方法,您可以将参数传递给这些方法。
  • 您甚至可以将一个枚举的实例作为参数传递给另一个枚举的实例的方法,就像您可以将枚举的实例传递给其他非枚举类的实例一样。每个枚举实例只是一个简单且简单的对象,另存为枚举定义类上的静态引用。

示例:

public enum Food { HERBIVORE, OMNIVORE, CARNIVORE ; }  // Syntactic sugar for automatically instantiating these named static instances of this class type.

…和…

public enum Animal {
    RABBIT( Food.HERBIVORE ) , 
    DOG( Food.OMNIVORE ) , 
    CAT( Food.CARNIVORE ) ;  

    // Member variables.
    public Food eats ; 

    // Constructor
    Animal( Food foodType ) {
        this.eats = foodType ;  // Assign an instance of another enum to this instance of this enum.
    }

}

枚举的限制

尽管比其他语言更强大和有用,但还是有局限性。

编译时间

首先,枚举在编译时定义。如果您的值在运行时更改,也许您想添加或删除项目,则枚举不合适。

永久保存在内存中

此外,枚举是静态的。这意味着,在首次使用该枚举类的所有对象时,它们会立即实例化并在整个应用程序执行期间保存在内存中。因此,它们永远不会从内存中退出,直到程序结束。因此拥有大量的内存可能会增加内存负担。

了解您可以收集枚举实例。有关枚举实例的快速执行和低内存使用情况集合,请参见EnumSetEnumMap类。搜索堆栈溢出以获取有关此主题的大量介绍。并且请注意,每个枚举都带有一个values()方法,该方法返回其值的数组,但是此方法是mysteriously not listed in the JavaDoc

至于您提到的继承,根据定义,您的枚举是Enum类的子类。因此,它们不能从您可能想到的任何其他类继承,因为Java不支持multiple-inheritance。您的枚举可以实现一个或多个接口。在更高版本的Java中,继承可以通过新的默认方法携带实现代码,因此您可以以这种方式传递一些代码。

国际化

Internationalization and localization似乎是一个正交的问题。您可以在枚举上添加一个方法以生成其值的本地化String表示形式。例如,请参见DayOfWeek::getDisplayNameMonth::getDisplayName枚举方法。

数据库

如果您想在运行时动态定义值,或者您有成千上万的值,那么数据库是行之有效的方法。诸如Postgres之类的重要数据库旨在管理内存,处理并发并有效执行。

您甚至可以将枚举与数据库结合在一起。例如,本地化。您可能在编译时定义了枚举值,但是它们的getDisplayName方法对数据库进行了查找,以查找法语或阿拉伯语翻译。可以通过在运行时通过JDBC运行SQL INSERTUPDATE命令来更新数据库中的转换值。

递归层次关系

如果您试图表示任意深度的层次结构的关系,那么这是一个完整的其他主题,除了说通常通过递归实现之外,这里不再赘述。搜索堆栈溢出和其他资源以了解更多信息。