Мы больше никогда не храним перечисления как числовые порядковые значения; это затрудняет отладку и поддержку. Мы сохраняем фактическое значение перечисления, преобразованное в строку:
public enum Suit { Spade, Heart, Diamond, Club }
Suit theSuit = Suit.Heart;
szQuery = "INSERT INTO Customers (Name, Suit) " +
"VALUES ('Ian Boyd', %s)".format(theSuit.name());
а затем прочитайте:
Suit theSuit = Suit.valueOf(reader["Suit"]);
Проблема заключалась в том, что раньше смотрели на Enterprise Manager и пытались расшифровать:
Name Suit
================== ==========
Shelby Jackson 2
Ian Boyd 1
вирши
Name Suit
================== ==========
Shelby Jackson Diamond
Ian Boyd Heart
последнее намного проще. Первое требовало доступа к исходному коду и нахождения числовых значений, которые были присвоены членам перечисления.
Да, он занимает больше места, но имена членов перечисления короткие, а жесткие диски дешевы, и гораздо больше стоит помочь, когда у вас возникнут проблемы.
Кроме того, если вы используете числовые значения, вы привязаны к ним. Вы не можете аккуратно вставить или переставить элементы без принудительного использования старых числовых значений. Например, изменение перечисления Suit на:
public enum Suit { Unknown, Heart, Club, Diamond, Spade }
должно было стать:
public enum Suit {
Unknown = 4,
Heart = 1,
Club = 3,
Diamond = 2,
Spade = 0 }
для сохранения устаревших числовых значений, хранящихся в базе данных.
Как их отсортировать в базе
Возникает вопрос: допустим, я хотел упорядочить значения. Некоторые люди могут захотеть отсортировать их по порядковому номеру перечисления. Конечно, упорядочивать карты по числовому значению перечисления бессмысленно:
SELECT Suit FROM Cards
ORDER BY SuitID; --where SuitID is integer value(4,1,3,2,0)
Suit
------
Spade
Heart
Diamond
Club
Unknown
Это не тот порядок, который нам нужен - мы хотим, чтобы они были в порядке перечисления:
SELECT Suit FROM Cards
ORDER BY CASE SuitID OF
WHEN 4 THEN 0 --Unknown first
WHEN 1 THEN 1 --Heart
WHEN 3 THEN 2 --Club
WHEN 2 THEN 3 --Diamond
WHEN 0 THEN 4 --Spade
ELSE 999 END
Та же работа, которая требуется при сохранении целочисленных значений, требуется при сохранении строк:
SELECT Suit FROM Cards
ORDER BY Suit; --where Suit is an enum name
Suit
-------
Club
Diamond
Heart
Spade
Unknown
Но это не тот порядок, который нам нужен - мы хотим, чтобы они были в порядке перечисления:
SELECT Suit FROM Cards
ORDER BY CASE Suit OF
WHEN 'Unknown' THEN 0
WHEN 'Heart' THEN 1
WHEN 'Club' THEN 2
WHEN 'Diamond' THEN 3
WHEN 'Space' THEN 4
ELSE 999 END
Я считаю, что такое ранжирование относится к пользовательскому интерфейсу. Если вы сортируете элементы на основе их значения перечисления: вы делаете что-то не так.
Но если бы вы действительно этого хотели, я бы создал Suits
таблицу измерений:
| Suit | SuitID | Rank | Color |
|------------|--------------|---------------|--------|
| Unknown | 4 | 0 | NULL |
| Heart | 1 | 1 | Red |
| Club | 3 | 2 | Black |
| Diamond | 2 | 3 | Red |
| Spade | 0 | 4 | Black |
Таким образом, если вы хотите изменить свои карты, чтобы использовать новый порядок колоды Kissing Kings, вы можете изменить его для отображения, не выбрасывая все свои данные:
| Suit | SuitID | Rank | Color | CardOrder |
|------------|--------------|---------------|--------|-----------|
| Unknown | 4 | 0 | NULL | NULL |
| Spade | 0 | 1 | Black | 1 |
| Diamond | 2 | 2 | Red | 1 |
| Club | 3 | 3 | Black | -1 |
| Heart | 1 | 4 | Red | -1 |
Теперь мы отделяем внутренние детали программирования (имя перечисления, значение перечисления) настройкой отображения, предназначенной для пользователей:
SELECT Cards.Suit
FROM Cards
INNER JOIN Suits ON Cards.Suit = Suits.Suit
ORDER BY Suits.Rank,
Card.Rank*Suits.CardOrder