2010-05-10 1 views
6

Как хранить 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; 
    } 
} 

Я читал другие подобные вопросы по этой теме, но проблема или решение не соответствует моей проблеме. Enum storage in Database field, Best method to store Enum in Database, Best way to store enum values in database - String or Int

ответ

3

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

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

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

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

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

8

В 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); 
    } 
} 
+0

Спасибо, это было прекрасное решение. Теперь я думал, что, возможно, мне захочется использовать значения в SQL-вычислениях в будущем, поэтому, возможно, мне следует сохранить значения в их собственной таблице db. – Jonas