Indizes in JPA definieren

1. Einleitung

In diesem Lernprogramm wird das Definieren von Indizes mithilfe der @ Index- Annotation von JPA erläutert . Anhand von Beispielen lernen wir, wie Sie unseren ersten Index mit JPA und Hibernate definieren. Danach werden wir die Definition ändern und zusätzliche Möglichkeiten zum Anpassen des Index anzeigen.

2. @ Index Annotation

Beginnen wir mit einer kurzen Zusammenfassung. Der Datenbankindex ist eine Datenstruktur, die die Geschwindigkeit von Datenabrufvorgängen für eine Tabelle auf Kosten zusätzlicher Schreibvorgänge und Speicherplatz verbessert . Meist handelt es sich um eine Kopie ausgewählter Datenspalten aus einer einzelnen Tabelle. Wir sollten Indizes erstellen, um die Leistung auf unserer Persistenzschicht zu erhöhen.

Mit JPA können wir dies erreichen, indem wir Indizes aus unserem Code mit @Index definieren . Diese Anmerkung wird vom Schemaerzeugungsprozess interpretiert, wodurch automatisch Artefakte erstellt werden. Beachten Sie, dass für unsere Entitäten kein Index angegeben werden muss.

Schauen wir uns nun die Definition an.

2.1. javax.persistence.Index

Die Indexunterstützung wurde schließlich in der JPA 2.1-Spezifikation von javax.persistence.Index hinzugefügt . Mit dieser Anmerkung können wir einen Index für unsere Tabelle definieren und entsprechend anpassen:

@Target({}) @Retention(RUNTIME) public @interface Index { String name() default ""; String columnList(); boolean unique() default false; }

Wie wir sehen können, ist nur das columnList- Attribut obligatorisch, das wir definieren müssen. Wir werden uns später die einzelnen Parameter genauer ansehen und Beispiele durchgehen.

2.2. JPA vs. Hibernate

Wir wissen, dass JPA nur eine Spezifikation ist. Um korrekt zu arbeiten, müssen wir auch einen Persistenzanbieter angeben. Standardmäßig ist das Hibernate Framework die von Spring bereitgestellte JPA-Implementierung. Mehr dazu können Sie hier lesen.

Wir sollten uns daran erinnern, dass die Indexunterstützung sehr spät zum JPA hinzugefügt wurde. Zuvor unterstützen viele ORM-Frameworks Indizes, indem sie eine eigene benutzerdefinierte Implementierung einführen, die möglicherweise anders funktioniert. Das Hibernate Framework hat dies ebenfalls getan und die Annotation org.hibernate.annotations.Index eingeführt . Während wir mit diesem Framework arbeiten, müssen wir darauf achten, dass es seit der Unterstützung der JPA 2.1-Spezifikation veraltet ist, und wir sollten das JPA verwenden.

Wenn wir nun einen technischen Hintergrund haben, können wir Beispiele durchgehen und unseren ersten Index in JPA definieren.

3. Definieren Sie den @Index

In diesem Abschnitt implementieren wir unseren Index. Später werden wir versuchen, es zu ändern und verschiedene Anpassungsmöglichkeiten vorzustellen.

Bevor wir beginnen, müssen wir unser Projekt ordnungsgemäß initialisieren und ein Modell definieren.

Lassen Sie uns eine Student- Entität implementieren :

@Entity @Table public class Student implements Serializable { @Id @GeneratedValue private Long id; private String firstName; private String lastName; // getters, setters }

Wenn wir unser Modell haben, implementieren wir den ersten Index. Wir müssen lediglich eine @ Index- Annotation hinzufügen . Wir machen das in der Annotation @Table unter dem Attribut indexes . Denken Sie daran, den Namen der Spalte anzugeben:

@Table(indexes = @Index(columnList = "firstName"))

Wir haben den allerersten Index mithilfe der Spalte firstName deklariert . Wenn wir den Schemaerstellungsprozess ausführen, können wir ihn validieren:

[main] DEBUG org.hibernate.SQL - create index IDX2gdkcjo83j0c2svhvceabnnoh on Student (firstName)

Jetzt ist es an der Zeit, unsere Erklärung mit zusätzlichen Funktionen zu ändern.

3.1. @Index Namen

Wie wir sehen können, muss unser Index einen Namen haben. Wenn wir dies nicht angeben, handelt es sich standardmäßig um einen vom Anbieter generierten Wert. Wenn wir ein eigenes Label haben wollen, sollten wir einfach den hinzufügen Name Attribut:

@Index(name = "fn_index", columnList = "firstName")

Diese Variante erstellt einen Index mit einem benutzerdefinierten Namen:

[main] DEBUG org.hibernate.SQL - create index fn_index on Student (firstName)

Darüber hinaus können wir unseren Index in den verschiedenen Schemas erstellen, indem wir den Namen des Schemas im Namen angeben :

@Index(name = "schema2.fn_index", columnList = "firstName")

3.2. mehrspaltigen @Index

Schauen wir uns nun die columnList- Syntax genauer an :

column ::= index_column [,index_column]* index_column ::= column_name [ASC | DESC]

Wie wir bereits wissen, können wir die Spaltennamen angeben, die in den Index aufgenommen werden sollen. Natürlich können wir dem einzelnen Index mehrere Spalten zuweisen. Wir tun dies, indem wir die Namen durch ein Komma trennen:

@Index(name = "mulitIndex1", columnList = "firstName, lastName") @Index(name = "mulitIndex2", columnList = "lastName, firstName")
[main] DEBUG org.hibernate.SQL - create index mulitIndex1 on Student (firstName, lastName) [main] DEBUG org.hibernate.SQL - create index mulitIndex2 on Student (lastName, firstName)

Beachten Sie, dass der Persistenzanbieter die angegebene Reihenfolge der Spalten einhalten muss. In unserem Beispiel unterscheiden sich die Indizes geringfügig, auch wenn sie denselben Satz von Spalten angeben.

3.3. @Index Bestellen

Wie wir die Syntax im vorherigen Abschnitt überprüft, auch wir können angeben ASC (aufsteigend) und DESC (absteigend) Werte nach dem column_name . Wir verwenden es, um die Sortierreihenfolge der Werte in der indizierten Spalte festzulegen:

@Index(name = "mulitSortIndex", columnList = "firstName, lastName DESC")
[main] DEBUG org.hibernate.SQL - create index mulitSortIndex on Student (firstName, lastName desc)

Wir können die Reihenfolge für jede Spalte angeben. Wenn wir dies nicht tun, wird die aufsteigende Reihenfolge angenommen.

3.4. @ Index Einzigartigkeit

The last optional parameter is a unique attribute, which defines whether the index is unique. A unique index ensures that the indexed fields don't store duplicate values. By default, it's false. If we want to change it, we can declare:

@Index(name = "uniqueIndex", columnList = "firstName", unique = true)
[main] DEBUG org.hibernate.SQL - alter table Student add constraint uniqueIndex unique (firstName)

When we create an index in that way, we add a uniqueness constraint on our columns, similarly, how as a unique attribute on @Column annotation do. @Index has an advantage over @Column due to the possibility to declare multi-column unique constraint:

@Index(name = "uniqueMulitIndex", columnList = "firstName, lastName", unique = true)

3.5. Multiple @Index on a Single Entity

So far, we've implemented different variants of the index. Of course, we're not limited to declaring a single index on the entity. Let's collect our declarations and specify every single index at once. We do that by repeating @Index annotation in braces and separated by a comma:

@Entity @Table(indexes = { @Index(columnList = "firstName"), @Index(name = "fn_index", columnList = "firstName"), @Index(name = "mulitIndex1", columnList = "firstName, lastName"), @Index(name = "mulitIndex2", columnList = "lastName, firstName"), @Index(name = "mulitSortIndex", columnList = "firstName, lastName DESC"), @Index(name = "uniqueIndex", columnList = "firstName", unique = true), @Index(name = "uniqueMulitIndex", columnList = "firstName, lastName", unique = true) }) public class Student implements Serializable

What is more, we can also create multiple indexes for the same set of columns.

3.6. Primary Key

When we talk about indexes, we have to stop for a while at primary keys. As we know, every entity managed by the EntityManager must specify an identifier that is mapped into the primary key.

Generally, the primary key is a specific type of unique index. It's worth adding that we don't have to declare the definition of this key in the way presented before. Everything is done automatically by the @Id annotation.

3.7. Non-entity @Index

After we've learned different ways to implement indexes, we should mention that @Table isn't the only place to specify them. In the same way, we can declare indexes in @SecondaryTable, @CollectionTable, @JoinTable, @TableGenerator annotations. Those examples aren't covered in this article. For more details, please check the javax.persistence JavaDoc.

4. Conclusion

In diesem Artikel haben wir das Deklarieren von Indizes mit JPA erläutert. Wir haben zunächst das allgemeine Wissen über sie überprüft. Später haben wir unseren ersten Index implementiert und anhand von Beispielen gelernt, wie Sie ihn anpassen können, indem Sie den Namen, die enthaltenen Spalten, die Reihenfolge und die Eindeutigkeit ändern. Am Ende sprachen wir über Primärschlüssel und zusätzliche Möglichkeiten und Orte, an denen wir sie deklarieren können.

Wie immer sind die Beispiele aus dem Artikel auf GitHub verfügbar.