列挙型をデータベースに保存する最適な方法は何ですか?
name()
Java には列挙値を文字列に変換したり、その逆の変換を行うメソッドが用意されていることは知っていますvalueOf()
。しかし、これらの値を格納する他の (柔軟な) オプションはありますか?
列挙型を一意の番号にするスマートな方法はありますか (ordinal()
使用するのは安全ではありません)?
アップデート
すばらしい迅速な回答をありがとうございました。予想通りでした。
ただし、ツールキット: これは 1 つの方法です。問題は、作成する各列挙型に同じメソッドを追加する必要があることです。これは重複するコードが多くなり、現時点では Java はこれに対するソリューションをサポートしていません (Java 列挙型は他のクラスを拡張できません)。
ベストアンサー1
私たちは一度もない列挙を数値の順序値として保存することはもうやめてください。デバッグとサポートが非常に難しくなります。実際の列挙値を文字列に変換して保存します。
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
------------ ----
Kylie Guénin 2
Ian Boyd 1
詩
Name Suit
------------ -------
Kylie Guénin 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 }
データベースに保存されている従来の数値を維持するためです。
データベース内での並び替え方法
ここで疑問が湧いてきます。値を順序付けしたいとします。 の序数値で並べ替えたい人もいるかもしれませんenum
。 もちろん、列挙の数値でカードを順序付けしても意味がありません。
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
寸法表:
スーツ | スーツID | ランク | 色 |
---|---|---|---|
未知 | 4 | 0 | ヌル |
心臓 | 1 | 1 | 赤 |
クラブ | 3 | 2 | 黒 |
ダイヤモンド | 2 | 3 | 赤 |
スペード | 0 | 4 | 黒 |
こうすることで、使用するカードを変更したいときにキスキング新しいデッキオーダーすべてのデータを破棄せずに、表示目的で変更することができます。
スーツ | スーツID | ランク | 色 | カード注文 |
---|---|---|---|---|
未知 | 4 | 0 | ヌル | ヌル |
スペード | 0 | 1 | 黒 | 1 |
ダイヤモンド | 2 | 2 | 赤 | 1 |
クラブ | 3 | 3 | 黒 | -1 |
心臓 | 1 | 4 | 赤 | -1 |
ここで、内部プログラミングの詳細 (列挙名、列挙値) とユーザー向けの表示設定を分離します。
SELECT Cards.Suit
FROM Cards
INNER JOIN Suits ON Cards.Suit = Suits.Suit
ORDER BY Suits.Rank,
Card.Rank*Suits.CardOrder