Как мне хранить Java Enum в JavaDB?

Как мне хранить Java Enum в JavaDB?

Должен ли я попытаться сопоставить перечисления с 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;
    }
}

Я читал другие похожие вопросы по этой теме, но проблема или решение не соответствуют моей проблеме. хранилище перечислений в поле базы данных, Лучший способ сохранить Enum в базе данных, Лучший способ хранить значения перечисления в базе данных - String или Int


person Jonas    schedule 10.05.2010    source источник


Ответы (2)


Я предпочитаю поступать следующим образом:

  • Создайте в базе данных специальную таблицу перечисления со столбцами: YourEnumId smallint, YourEnumName varchar (32).
  • В таблице бизнес-объектов добавьте ссылки на внешние ключи в таблицу перечисления.
  • Внедрите свой Java DAO для сопоставления значений перечисления с значениями smallint для конкретной базы данных при сохранении данных ИЛИ реализуйте хранимые процедуры, которые принимают имя перечисления (например, varchar) и переводят его в smallint при записи данных.

Преимущества

  • Повышенная нормализация (и, следовательно, меньшие накладные расходы на хранилище) по сравнению с сохранением строкового значения явным образом в таблице базы данных.
  • Данные вашей базы данных не будут повреждены, если ваше определение java enum изменится (например, если вы измените порядок значений).
  • Ваш класс DAO может выйти из строя во время инициализации, проверив, что определение перечисления Java соответствует содержимому таблицы YourEnum.
  • Вы можете предоставить представления в базе данных, которые возвращают значения перечисления String (например, если вы или пользователь хотите напрямую запросить таблицу).

Это похоже на решение cletus, за исключением того, что кодировка enum явно хранится в базе данных, а не определяется как часть определения перечисления.

person Adamski    schedule 10.05.2010

В JPA у вас есть два варианта:

  1. По имени;

  2. По порядковому номеру (целому).

Мне не нравится (2). Если вы измените порядок своего перечисления, он сломается. Таким образом, чаще используется (1) (по моему опыту).

Я бы сделал то же самое в JavaDB. Просто сохраните имя перечисления как текст. Его преимущество заключается в том, что вы можете смотреть на строку и знать, что она означает, вместо того, чтобы пытаться выяснить, что означает «3» в столбце status_id.

Если вас беспокоит пространство (а меня в 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);
  }
}
person cletus    schedule 10.05.2010
comment
Спасибо, хорошее решение. Теперь я подумал, что, может быть, я хотел бы использовать значения в SQL-вычислениях в будущем, поэтому, возможно, мне следует сохранить значения в их собственной таблице db. - person Jonas; 10.05.2010