7

我应该如何在 JavaDB 中存储 Java 枚举?

我应该尝试将枚举映射到SMALLINT源代码并将值保留在源代码中吗?嵌入式数据库仅由单个应用程序使用。或者我应该将值存储为DECIMAL?这些解决方案对我来说都没有感觉好/强大。有没有更好的选择?

这是我的枚举:

import java.math.BigDecimal;

public enum Vat {
    NORMAL(new BigDecimal("0.25")),
    FOOD(new BigDecimal("0.12")),
    BOOKS(new BigDecimal("0.06")),
    NONE(new BigDecimal("0.00"));

    private final BigDecimal value;

    Vat(BigDecimal val) {
        value = val;
    }

    public BigDecimal getValue() {
        return value;
    }
}

我已阅读有关此主题的其他类似问题,但问题或解决方案与我的问题不匹配。数据库字段中的枚举存储,将枚举存储在数据库中的最佳方法,将枚举值存储在数据库中的最佳方法 - 字符串或整数

4

2 回答 2

9

在 JPA 中,您有两种选择:

  1. 按名字;

  2. 按序数(整数)。

我不喜欢(2)。如果您更改枚举的顺序,它会中断。因此,使用 (1) 更常见(根据我的经验)。

我会在 JavaDB 中做同样的事情。只需将枚举名称存储为文本。它的优点是您可以查看一行并知道它的含义,而不是试图弄清楚 status_id 列中的“3”是什么意思。

如果您担心空间(99% 的时间我不会),请使用整数或使用代码。例如:

public enum Vat {
  NORMAL(new BigDecimal("0.25")),
  FOOD(new BigDecimal("0.12")),
  BOOKS(new BigDecimal("0.06")),
  NONE(new BigDecimal("0.00"));

  private static final Map<String, Vat> LOOKUP = new HashMap<String, Vat>();

  static {
    Vat[] values = values();
    for (Vat vat : values) {
      LOOKUP.put(vat.code, vat);
    }
  }

  private final String code;
  private final String value;

  private Vat(String code, BigDecimal value) {
    this.code = code;
    this.value = value;
  }

  public String getCode() { return code; }
  public String getValue() { return value; }

  public Vat fromCode(String code) {
    return LOOKUP.get(code);
  }
}
于 2010-05-10T10:44:34.553 回答
4

我的偏好是执行以下操作:

  • 在数据库中创建一个专用枚举表,其中包含以下列:YourEnumId smallint、YourEnumName varchar(32)。
  • 在您的业务对象表中添加对枚举表的外键引用。
  • 实现 Java DAO 以在持久化数据时将枚举值映射到特定于数据库的smallint 值,或者实现接受枚举名称(即 varchar)并在写入数据时将其转换为 smallint 的存储过程。

好处

  • 与将字符串值显式存储在数据库表中相比,增加了规范化(因此降低了存储开销)。
  • 如果您的 java 枚举定义更改(例如,如果您更改值的顺序),您的数据库数据将不会损坏。
  • 通过检查 Java 枚举定义是否与表的内容匹配,您的 DAO 类可以在初始化期间快速失败YourEnum
  • 您可以提供返回字符串枚举值的数据库视图(例如,如果您或用户希望直接查询表)。

这类似于 cletus 的解决方案,只是枚举编码显式存储在数据库中,而不是定义为枚举定义的一部分。

于 2010-05-10T11:09:05.743 回答