7

Java Enum を 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、 Enum をデータベースに格納する最良の方法 、 Enum値をデータベースに格納する最良の方法 - String または Int

4

2 に答える 2

9

JPA では、次の 2 つの選択肢があります。

  1. 名前で;

  2. 序数 (整数)。

私は(2)が好きではありません。列挙型の順序を変更すると、壊れます。そのため、(1)を使用するのがより一般的です(私の経験では)。

JavaDBでも同じことをします。列挙名をテキストとして保存するだけです。status_id 列の「3」が何を意味するのかを理解しようとするのではなく、行を見てその意味を知ることができるという利点があります。

スペースが気になる場合は (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);
  }
}
于 2010-05-10T10:44:34.553 に答える
4

私の好みは次のようにすることです:

  • YourEnumId smallint、YourEnumName varchar(32) という列を使用して、データベースに専用の列挙型テーブルを作成します。
  • ビジネス オブジェクト テーブル内で、列挙テーブルへの外部キー参照を追加します。
  • Java DAO を実装して、データを永続化するときに列挙型の値をデータベース固有のsmallint 値にマップするか、列挙型の名前 (つまり、varchar) を受け入れてデータの書き込み時にそれを smallint に変換するストアド プロシージャを実装します。

利点

  • データベース テーブルに明示的に文字列値を格納する場合と比較して、正規化が向上します (したがって、ストレージ オーバーヘッドが低くなります)。
  • Java 列挙型の定義が変更されても (値の順序を変更した場合など)、データベース データが破損することはありません。
  • DAO クラスは、Java 列挙型の定義がテーブルの内容と一致することを確認することで、初期化中にフェールファストYourEnumにすることができます。
  • String 列挙値を返すデータベースにビューを提供できます (たとえば、あなたまたはユーザーがテーブルを直接クエリしたい場合)。

これは、列挙エンコーディングが列挙定義の一部として定義されるのではなく、データベースに明示的に格納されることを除いて、cletus のソリューションに似ています。

于 2010-05-10T11:09:05.743 に答える