Mapim 列挙型

プリミティブ データ型をマップする方法はすでに理解しています。 @Columnアノテーションと@Typeアノテーションを使用します。ただし、すべてのケースをこれらの注釈でカバーできるわけではありません。最も一般的なケースはenumです。

Java enum オブジェクトは、次の 2 つの方法でデータベースに保存できます。

  • 数字として
  • 文字列として

ユーザーが好みの色を持ち、それを enum を使用して設定する小さな例を書いてみましょう。


enum Color {
   RED,
   ORANGE,
   YELLOW,
   GREEN,
   BLUE,
   VIOLET
}

そして、 Userクラスにカラーフィールドを追加します。


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Column(name="favorite_color")
   public Color favoriteColor;
 
   @Column(name="created_date")
   public Date createdDate;
}

Hibernate に Color タイプを数値としてベースに保存させたい場合は、フィールドが必要です。好きな色注釈を追加します:


@Enumerated(EnumType.ORDINAL)

値を文字列として保存したい場合は、注釈を追加する必要があります。


@Enumerated(EnumType.STRING)

例:


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Enumerated(EnumType.ORDINAL) //value will be saved to the base as a number
   @Column(name="favorite_color")
   public Color favoriteColor;
 
   @Column(name="created_date")
   public Date createdDate;
}

マピムブール値

2 番目の有用なシナリオは、ブール型マッピングです。SQL にはブール値の独自のデータ型がなく、代わりに何でも使用されるのは歴史的に偶然です。

最も一般的なオプションは次の 3 つです。

  • 1 または 0
  • 「F」または「T」
  • 「Y」または「N」

一般に、ベースを設計する場合は、すぐに BIT タイプを記述することをお勧めします。完全なマッピングは次のようになります。


	@Column(name = "is_correct", columnDefinition = "BIT")
	@Type(type = "org.hibernate.type.NumericBooleanType")
    private Boolean isCorrect;

データベースを設計していない場合は、上の表を参照して、必要な型を正しくマップする方法を考えてください。

計算フィールド

エンティティ クラスのフィールドの数とテーブルの列の数が一致しない場合があります。これにはいくつかの理由が考えられます。

最も一般的なのは、データベースに保存したくないフィールドが Entity クラスにある場合です。これですべてが明確になります。そのようなフィールドに@Transientアノテーションを追加するだけで、Hibernate はデータベースを操作するときにそれを無視します。

例:


@Entity(name = "Square")
public class Square {
           	@Id
           	public Long id;
 
           	public Integer width;
 
           	public Integer height;
 
           	@Transient
           	public Integer total;
}

これは良いオプションですが、データベースからオブジェクトを読み取る場合、合計フィールドは null になります。そして、幅*高さの積を含めたいと考えています。これは休止状態でも実行できます。これには特別な@Formulaアノテーションがあります。


@Entity(name = "Square")
public class Square {
           	@Id
           	public Long id;
 
           	public Integer width;
 
           	public Integer height;
 
           	@Formula(value = " width * height ")
          	public Integer total;
}

このようなフィールドはデータベースには保存されず、オブジェクトがデータベースから読み取られるときに、式によって計算された値が書き込まれます。

SQL クエリは次のようになります。

 SELECT id, width, height, (width* height) AS total FROM Square;

@埋め込み

もう 1 つの便利なアノテーションは@Embeddedです。これにより、子オブジェクトのフィールドを Entity クラス自体のフィールドとみなすことができます。

Userクラスがあり、それにアドレスを追加するとします。


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
    public Integer id;
 
   @Column(name="user_address_country")
   public String country;
   @Column(name="user_address_city")
   public String city;
   @Column(name="user_address_street")
   public String street;
   @Column(name="user_address_home")
   public String home;
 
   @Column(name="created_date")
    public Date createdDate;
}

すべて問題ないようですが、Java の観点からは、アドレスを別のクラスに置くのが論理的です。住所は依然として別個のエンティティです。しかし、このすべての情報がデータベースの user テーブルに保存されている場合、これをどのように行うのでしょうか?

@Embeddedアノテーションが役に立ちます。まず、 UserAddressクラスを作成し、ユーザーのアドレスに関するすべての情報をそのクラスに入れます。


@Embeddable
class UserAddress
{
   @Column(name="user_address_country")
   public String country;
   @Column(name="user_address_city")
   public String city;
   @Column(name="user_address_street")
   public String street;
   @Column(name="user_address_home")
   public String home;
}

次に、このクラスのフィールドをUserクラスで使用します。


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Embedded
   public UserAddress address;
 
   @Column(name="created_date")
   public Date createdDate;
}

@Embeddedアノテーションのおかげで、オブジェクトの保存時に、Hibernate はUserAddressクラスのフィールドをUserクラス自体のフィールドとして扱う必要があることを理解します。

重要!Userクラスに2 つのUserAddressフィールドを追加することにした場合、@Embeddedの使用は機能しなくなります。フィールドが重複するため、何らかの方法でそれらを分離する必要があります。これは、 @AttributeOverridesアノテーションを使用してアノテーションをオーバーライドすることによって行われます。

これを知っておいてほしいのですが、ここでは詳しく説明しません。頭が壊れるにはこれで十分だと思います。興味がある方のために、公式ドキュメントへのリンクを残しておきます。