Как мне хранить Java Enum в JavaDB? - PullRequest
7 голосов
/ 10 мая 2010

Как мне хранить 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 в базе данных , Лучший способ хранения Enum в базе данных , Лучший способ хранения значений перечисления в базе данных - String или Int

Ответы [ 2 ]

9 голосов
/ 10 мая 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);
  }
}
4 голосов
/ 10 мая 2010

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

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

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

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

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

...