1. ホーム
  2. java

[解決済み] データベースに列挙型を保存する方法

2022-06-01 05:48:34

質問

データベースに列挙型を保存する最も良い方法は何ですか?

私は、Javaが name()valueOf() メソッドを使用して、enum 値を String に変換したり戻したりすることができます。しかし、これらの値を格納するための他の(柔軟な)オプションがあるでしょうか?

enumをユニークな数字にするスマートな方法はありますか ( ordinal() を使用するのは安全ではありません)?

更新しました。

すべての素晴らしい、迅速な回答をありがとうございました それは私が思った通りでした。

しかし、'toolkit'へのメモ; それは1つの方法です。問題は、私が作成する各 Enum 型に同じメソッドを追加しなければならないことです。これは多くの重複したコードであり、現時点では、Javaはこのためのいかなる解決策もサポートしていません(Javaのenumは他のクラスを拡張することはできません)。

どのように解決するのですか?

私たちは は決して それはデバッグとサポートを非常に困難にします。デバッグやサポートが非常に困難になるからです。私たちは文字列に変換された実際の列挙値を保存します。

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 NULL
心臓 1 1 赤色
クラブ 3 2
ダイヤモンド 2 3 赤色
スペード 0 4

こうすることで、カードを変更したいときに キスキングス ニューデックオーダー のようにすれば、データを捨てずに表示用に変更することができます。

スーツ スーツID ランク カードオーダー
不明 4 0 NULL NULL
スペード 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