JPAでの一意の制約の定義
1. 序章
このチュートリアルでは、JPAとHibernateを使用した一意の制約の定義について説明します。
最初に、固有の制約と、それらが主キー制約とどのように異なるかを調べます。
次に、JPAの重要な注釈@を見ていきます。 列(一意= true) と
最後に、参照されるテーブル列に一意の制約を定義する方法を学習します。
2. 固有の制約
簡単な要約から始めましょう。 一意キーは、データベーステーブル内のレコードを一意に識別するテーブルの単一または複数の列のセットです。
一意キー制約と主キー制約の両方が、列または列のセットの一意性を保証します。
2.1. 主キーの制約とどのように違いますか?
一意の制約により、列または列の組み合わせのデータが各行で一意になります。 たとえば、テーブルの主キーは、暗黙の一意性制約として機能します。 したがって、主キー制約には自動的に一意の制約があります。
さらに、テーブルごとに1つの主キー制約のみを持つことができます。 ただし、テーブルごとに複数の一意の制約が存在する可能性があります。 簡単に言えば、主キーマッピングに伴う制約に加えて、一意の制約が適用されます。
定義した一意の制約は、テーブルの作成時に適切なデータベース制約を生成するために使用されます。また、実行時に挿入、更新、または削除を注文するために使用される場合もあります。ステートメント。
2.2. 単一列および複数列の制約とは何ですか?
一意の制約は、列制約またはテーブル制約のいずれかです。 テーブルレベルでは、複数の列にまたがる一意の制約を定義できます。
何よりもまず、列レベルの制約は単一の列に適用され、テーブルレベルの制約はテーブル全体に適用されることを強調する必要があります。
これについては、次のセクションで詳しく説明します。
3. エンティティを設定する
JPAのentityは、データベースに格納されているテーブルを表します。 エンティティのすべてのインスタンスは、テーブル内の行を表します。
ドメインエンティティを作成し、それをデータベーステーブルにマッピングすることから始めましょう。 この例では、 Personentityを作成します。
@Entity
@Table
public class Person implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
private String password;
private String email;
private Long personNumber;
private Boolean isActive;
private String securityNumber;
private String departmentCode;
@JoinColumn(name = "addressId", referencedColumnName = "id")
private Address address;
//getters and setters
}
address フィールドは、Addressエンティティからの参照フィールドです。
@Entity
@Table
public class Address implements Serializable {
@Id
@GeneratedValue
private Long id;
private String streetAddress;
//getters and setters
}
このチュートリアル全体を通して、このPersonエンティティを使用して例を示します。
4. 列の制約
モデルの準備ができたら、最初の一意の制約を実装できます。
個人の情報を保持するPersonエンティティについて考えてみましょう。 id列の主キーがあります。 このエンティティは、重複する値を含まない PersonNumber、も保持します。 さらに、テーブルにすでに主キーがあるため、主キーを定義できません。
この場合、列の一意の制約を使用して、PersonNumberフィールドに重複する値が入力されないようにすることができます。 JPAでは、unique属性を持つ@Columnアノテーションを使用してこれを実現できます。
次のセクションでは、 @Column アノテーションを見て、それを実装する方法を学びます。
4.1. @Column(unique = true)
注釈タイプColumnは、永続プロパティまたはフィールドのマップされた列を指定するために使用されます。
定義を見てみましょう:
@Target(value={METHOD,FIELD})
@Retention(value=RUNTIME)
public @interface Column {
boolean unique;
//other elements
}
unique 属性は、列が一意のキーであるかどうかを指定します。 これは、 UniqueConstraint アノテーションのショートカットであり、一意キー制約が単一の列のみに対応する場合に役立ちます。
次のセクションでそれを定義する方法を見ていきます。
4.2. 列制約の定義
一意の制約が1つのフィールドのみに基づいている場合は常に、その列で @Column(unique = true)を使用できます。
personNumberフィールドに一意の制約を定義しましょう。
@Column(unique=true)
private Long personNumber;
スキーマ作成プロセスを実行すると、ログから検証できます。
[main] DEBUG org.hibernate.SQL -
alter table Person add constraint UK_d44q5lfa9xx370jv2k7tsgsqt unique (personNumber)
同様に、 Person を制限して一意の電子メールに登録する場合は、emailフィールドに一意の制約を追加できます。
@Column(unique=true)
private String email;
スキーマ作成プロセスを実行して、制約を確認しましょう。
[main] DEBUG org.hibernate.SQL -
alter table Person add constraint UK_585qcyc8qh7bg1fwgm1pj4fus unique (email)
これは、単一の列に一意の制約を設定する場合に便利ですが、列の組み合わせである複合キーに一意の制約を追加したい場合があります。 複合一意キーを定義するために、テーブル制約を使用できます。 これについては、次のセクションで説明します。
5. テーブルの制約
複合一意キーは、列の組み合わせで構成される一意キーです。
5.1. @UniqueConstraintアノテーション
注釈タイプUniqueConstraintは、テーブル用に生成されたDDL(データ定義言語)に一意の制約を含めることを指定します。
定義を見てみましょう:
@Target(value={})
@Retention(value=RUNTIME)
public @interface UniqueConstraint {
String name() default "";
String[] columnNames();
}
ご覧のとおり、タイプStringおよびString []のnameおよびcolumnNamesは、それぞれ、UniqueConstraintアノテーションに指定できるアノテーション要素です。
次のセクションでは、例を見て、各パラメーターを詳しく見ていきます。
5.2. 一意の制約の定義
Personエンティティについて考えてみましょう。 Person には、アクティブステータスの重複レコードがあってはなりません。 つまり、personNumberとisActiveで構成されるキーの値が重複することはありません。 ここでは、複数の列にまたがる一意の制約を追加する必要があります。
JPAは、@UniqueConstraintアノテーションを使用してこれを実現するのに役立ちます。 uniqueConstraints属性の下の@Tableアノテーションで使用します。 列の名前を指定することを忘れないでください。
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "personNumber", "isActive" }) })
スキーマが生成されたら、それを検証できます。
[main] DEBUG org.hibernate.SQL -
alter table Person add constraint UK5e0bv5arhh7jjhsls27bmqp4a unique (personNumber, isActive)
ここで注意すべき点の1つは、名前を指定しない場合、それはプロバイダーによって生成された値であるということです。 JPA 2.0以降、一意の制約に名前を付けることができます。
@Table(uniqueConstraints = { @UniqueConstraint(name = "UniqueNumberAndStatus", columnNames = { "personNumber", "isActive" }) })
そして、同じことを検証できます。
[main] DEBUG org.hibernate.SQL -
alter table Person add constraint UniqueNumberAndStatus unique (personNumber, isActive)
ここでは、一連の列に一意の制約を追加しました。 複数の一意の制約を追加することもできます。つまり、複数の列セットに一意の制約を追加できます。 次のセクションでそれを行います。
5.3. 単一のエンティティに対する複数の一意の制約
テーブルには複数の一意の制約を設定できます。前のセクションでは、複合キーに一意の制約を定義しました:personNumberおよびisActiveステータス。 このセクションでは、securityNumberとdepartmentCodeの組み合わせに制約を追加します。
一意のインデックスを収集して、一度に指定しましょう。 これを行うには、 @UniqueConstraint アノテーションを中かっこで繰り返し、コンマで区切ります。
@Table(uniqueConstraints = {
@UniqueConstraint(name = "UniqueNumberAndStatus", columnNames = {"personNumber", "isActive"}),
@UniqueConstraint(name = "UniqueSecurityAndDepartment", columnNames = {"securityNumber", "departmentCode"})})
次に、ログを確認して、制約を確認しましょう。
[main] DEBUG org.hibernate.SQL -
alter table Person add constraint UniqueNumberAndStatus unique (personNumber, isActive)
[main] DEBUG org.hibernate.SQL -
alter table Person add constraint UniqueSecurityAndDepartment unique (securityNumber, departmentCode)
これまで、同じエンティティ内のフィールドに一意の制約を定義していました。 ただし、場合によっては、他のエンティティからフィールドを参照している可能性があり、それらのフィールドの一意性を確認する必要があります。 これについては、次のセクションで説明します。
6. 参照テーブル列に対する一意の制約
相互に関連する2つ以上のテーブルを作成する場合、それらは多くの場合、一方のテーブルの列が他方のテーブルの主キーを参照することによって関連付けられます。 その列は「外部キー」と呼ばれます。 たとえば、PersonおよびAddressエンティティは、addressIdフィールドを介して接続されます。 したがって、addressIdは参照テーブル列として機能します。
参照される列に一意の制約を定義できます
6.1. 単一列の制約
Person エンティティには、Addressエンティティを参照するaddressフィールドがあります。 personには一意のアドレスが必要です。
それでは、Personのaddressフィールドに一意の制約を定義しましょう。
@Column(unique = true)
private Address address;
次に、この制約を簡単に確認しましょう。
[main] DEBUG org.hibernate.SQL -
alter table Person add constraint UK_7xo3hsusabfaw1373oox9uqoe unique (address)
次のセクションで説明するように、参照されるテーブルの列に複数の列の制約を定義することもできます。
6.2. 複数列の制約
列の組み合わせに一意の制約を指定できます。 前に述べたように、テーブル制約を使用してこれを行うことができます。
personNumberおよびaddress、に一意の制約を定義し、それをuniqueConstraints配列に追加しましょう。
@Entity
@Table(uniqueConstraints =
{ //other constraints
@UniqueConstraint(name = "UniqueNumberAndAddress", columnNames = { "personNumber", "address" })})
最後に、固有の制約を見てみましょう。
[main] DEBUG org.hibernate.SQL -
alter table Person add constraint UniqueNumberAndAddress unique (personNumber, address)
7. 結論
一意の制約により、2つのレコードが1つの列または列のセットで同じ値を持つことはできません。
この記事では、JPAで一意の制約を定義する方法を学びました。 まず、固有の制約について少し要約しました。 次に、 @Column(unique = true)および @UniqueConstraint アノテーションについて説明し、それぞれ単一の列と複数の列に一意の制約を定義しました。
いつものように、この記事の例はGitHubでから入手できます。