Как я должен сохранить Перечисление Java в JavaDB?

Как я должен сохранить Перечисление Java в 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;
    }
}

Я считал другие подобные вопросы по этой теме, но проблема или решение не соответствуют моей проблеме. Перечислимое устройство хранения данных в поле Database, Лучший метод для хранения Перечисления в Базе данных, Лучший способ сохранить перечислимые значения в базе данных - Строка или Интервал

7
задан Community 23 May 2017 в 12:32
поделиться

2 ответа

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

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

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

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

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

4
ответ дан 6 December 2019 в 19:34
поделиться

В 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);
  }
}
9
ответ дан 6 December 2019 в 19:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: