web-dev-qa-db-ja.com

JPAを使用したインデックス(非一意キー)の指定

JPAアノテーションを使用してインデックスを持っているとしてemailなどのフィールドをどのように定義しますか。 emailには一意でないキーが必要です。なぜなら、このフィールドには文字通り何百万ものクエリがあり、キーなしでは少し遅いからです。

@Entity
@Table(name="person", 
       uniqueConstraints=@UniqueConstraint(columnNames={"code", "uid"}))
public class Person {
    // Unique on code and uid
    public String code;
    public String uid;

    public String username;
    public String name;
    public String email;
}

ハイバネート固有のアノテーションを見てきましたが、まだハイバネートとデータニュークリアスを決定しているため、ベンダー固有のソリューションを回避しようとしています。

更新:

JPA 2.1以降、これを行うことができます。参照: アノテーション@Indexはこの場所では許可されていません

82
Jacob

私の知る限り、JPAプロバイダー間でインデックスを指定する方法はありません。ただし、データベースで直接手作業でいつでも作成できます。ほとんどのデータベースは、クエリの計画時に自動的に取得します。

4

JPA 2.1を使用すると、これを実行できるはずです。

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;

@Entity
@Table(name = "region",
       indexes = {@Index(name = "my_index_name",  columnList="iso_code", unique = true),
                  @Index(name = "my_index_name2", columnList="name",     unique = false)})
public class Region{

    @Column(name = "iso_code", nullable = false)
    private String isoCode;

    @Column(name = "name", nullable = false)
    private String name;

} 

更新:2つ以上の列を作成してインデックスを作成する必要がある場合は、カンマを使用できます。例えば:

@Entity
@Table(name    = "company__activity", 
       indexes = {@Index(name = "i_company_activity", columnList = "activity_id,company_id")})
public class CompanyActivity{
174
borjab

JPA 2.1(最終的に)は、インデックスと外部キーのサポートを追加します!詳細については このブログ をご覧ください。 JPA 2.1はJava EE 7の一部です。

Edgeでの生活が好きな場合は、 mavenリポジトリ (groupId:org.Eclipse.persistence、artifactId:eclipselink、version:2.5.0-SNAPSHOT)からeclipselinkの最新のスナップショットを取得できます。 JPAアノテーション(2.1をサポートするプロバイダーであれば動作するはずです)のみに対して、artifactID:javax.persistence、version:2.1.0-SNAPSHOTを使用します。

リリース後まで終了しないプロジェクトに使用していますが、恐ろしい問題に気づいていません(複雑なことはしていませんが)。

更新(2013年9月26日):中央(メイン)リポジトリでeclipselinkのリリースおよびリリース候補バージョンが利用できるようになったため、Mavenプロジェクトにeclipselinkリポジトリを追加する必要がなくなりました。最新リリースバージョンは2.5.0ですが、2.5.1-RC3も存在します。 2.5.0リリースの問題のため、できるだけ早く2.5.1に切り替えます(modelgenの機能は動作しません)。

30
Alvin Thompson

独自の厳選されたインデックスアノテーションのコレクション

=仕様=

= [〜#〜] orm [〜#〜] フレームワーク=

= Android のORM =

=その他(分類が難しい)=

  • Realm -iOS/Android用の代替DB:注釈 io.realm.annotations.Index ;
  • Empire-db -JDBCに基づく軽量で強力なリレーショナルDB抽象化レイヤー。注釈によるスキーマ定義はありません。
  • Kotlin NoSQL (GitHub) -NoSQLデータベース(PoC)を操作するためのリアクティブでタイプセーフなDSL:???
  • Slick -Scalaのリアクティブ機能リレーショナルマッピング。注釈によるスキーマ定義はありません。

そのうちの1つに行くだけです。

30
naXa

JPA 2.1では、次のことを行う必要があります

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.Table;

@Entity(name="TEST_PERSON")
@Table(
    name="TEST_PERSON", 
    indexes = {
       @Index(name = "PERSON_INDX_0", columnList = "age"),
       @Index(name = "PERSON_INDX_1", columnList = "fName"),
       @Index(name = "PERSON_INDX_1", columnList = "sName")  })
public class TestPerson {

    @Column(name = "age", nullable = false)
    private int age;

    @Column(name = "fName", nullable = false)
    private String firstName;

    @Column(name = "sName", nullable = false)
    private String secondName;

    @Id
    private long id;

    public TestPerson() {
    }
}

上記の例では、テーブルTEST_PERSONには3つのインデックスがあります。

  • 主キーIDの一意のインデックス

  • aGEのインデックス

  • fNAME、SNAMEの複合インデックス

注1:同じ名前の@Indexアノテーションを2つ持つことで複合インデックスを取得します

注2:fieldNameではなくcolumnListで列名を指定します

8
James Clayton

標準化された方法でデータベースインデックスを指定できるようにしたいのですが、残念ながら、これはJPA仕様の一部ではありません(おそらく、JPA仕様ではDDL生成サポートが必要ないためです。そのような機能)。

そのため、プロバイダー固有の拡張機能に依存する必要があります。 Hibernate、OpenJPA、EclipseLinkは明らかにこのような拡張機能を提供します。 DataNucleusについては確認できませんが、インデックスの定義はJDOの一部なので、そうなると思います。

インデックスのサポートが仕様の次のバージョンで標準化されることを本当に望みます。したがって、何らかの形で他の答えに同意しません。JPAにそのようなものを含めない理由はありません(特にデータベースは常に制御されているわけではないため)最適なDDL生成サポート。

ところで、JPA 2.0仕様をダウンロードすることをお勧めします。

5
Pascal Thivent

EclipseLinkは、列のインデックスを定義するための注釈(たとえば @ Index )を提供しました。 が使用されています。例の一部が含まれています...

FirstNameフィールドとlastNameフィールドには、一緒に個別にインデックスが作成されます。

@Entity
@Index(name="EMP_NAME_INDEX", columnNames={"F_NAME","L_NAME"})  // Columns indexed together
public class Employee{
    @Id
    private long id;

    @Index                      // F_NAME column indexed
    @Column(name="F_NAME")
    private String firstName;

    @Index                      // L_NAME column indexed
    @Column(name="L_NAME")
    private String lastName;
    ...
}
2
Nathan

他の答えを要約するには:

私はそれらの1つだけに行きます。とにかくJPA 2.1に付属し、JPAプロバイダーを本当に切り替えたい場合に変更するのはそれほど難しくないはずです。

1
Jack

OpenJPAでは、非標準の注釈を指定して、プロパティのインデックスを定義できます。

詳細は こちら です。

1
expert

このソリューションはEclipseLink 2.5用であり、動作します(テスト済み)。

@Table(indexes = {@Index(columnList="mycol1"), @Index(columnList="mycol2")})
@Entity
public class myclass implements Serializable{
      private String mycol1;
      private String mycol2;
}

これは、昇順を前提としています。

0
Joe Almore

JPAアノテーションを使用してそれを行うことはできません。そして、これは理にかなっています:UniqueConstraintがビジネスルールを明確に定義している場合、インデックスは検索を高速化するための単なる方法です。したがって、これは実際にDBAが行う必要があります。

0