Spanner in Spring Data einbinden

Das Spring Data Spanner-Modul unterstützt Sie bei der Verwendung von Spanner in jeder Java-Anwendung, die mit dem Spring Framework erstellt wurde.

Wie alle Spring Data-Module bietet Spring Data Spanner ein Spring-basiertes Programmiermodell, das die Konsistenzgarantien und die Skalierbarkeit von Spanner beibehält. Die Funktionen ähneln Spring Data JPA und Hibernate ORM und enthalten Anmerkungen, die für Spanner entwickelt wurden. Weitere Informationen zur Verwendung von Spring Data JPA mit Spanner finden Sie unter Spanner mit Spring Data JPA einbinden (GoogleSQL-Dialekt).

Wenn Sie bereits mit Spring vertraut sind, kann Spring Data Spanner die Arbeit mit Spanner in Ihrer Anwendung vereinfachen und die Menge an Code reduzieren, den Sie schreiben müssen.

Auf dieser Seite wird erläutert, wie Sie Spring Data Spanner einer Java-Anwendung hinzufügen. Ausführliche Informationen zum Modul finden Sie in der Referenz zu Spring Data Spanner.

Modul installieren

Wenn Sie Maven verwenden, fügen Sie die Materialliste von Spring Cloud GCP und Spring Data Spanner in die Datei pom.xml ein. Diese Abhängigkeiten stellen die Spring Data Spanner-Komponenten für Ihren Spring-ApplicationContext bereit:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>spring-cloud-gcp-dependencies</artifactId>
      <version>3.7.7</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>${spring.boot.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>spring-cloud-gcp-starter-data-spanner</artifactId>
  </dependency>
</dependencies>

Außerdem müssen Sie ein Dienstkonto erstellen und den Dienstkontoschlüssel zum Authentifizieren bei Google Cloud verwenden.

Weitere Informationen finden Sie in der Anleitung zum Java-Entwicklungsumgebung einrichten. Sie müssen die Google Cloud-Clientbibliothek für Java nicht installieren. Der Spring Boot-Starter installiert die Clientbibliothek automatisch.

Modul konfigurieren

In diesem Abschnitt werden einige der am häufigsten verwendeten Konfigurationseinstellungen für Spring Data Spanner beschrieben. Eine vollständige Liste der Einstellungen finden Sie in der Referenzdokumentation.

Instanz und Datenbank angeben

Um die Standardinstanz und -datenbank anzugeben, legen Sie die folgenden Konfigurationsattribute für Ihre Anwendung fest:

Attribut Beschreibung
spring.cloud.gcp.spanner.project-id Optional. Die Google Cloud-Projekt-ID. Überschreibt den Wert von spring.cloud.gcp.config.project-id.
spring.cloud.gcp.spanner.instance-id Die Spanner-Instanz-ID.
spring.cloud.gcp.spanner.database Die Datenbank, zu der eine Verbindung hergestellt werden soll.

Spanner-Daten modellieren

Mit Spring Data Spanner können Sie einfache alte Java-Objekte (POJOs) verwenden, um die Daten zu modellieren, die Sie in Ihren Spanner-Tabellen speichern.

Deklarieren Sie für jede Tabelle in der Datenbank eine Entität, die einen Datensatz in dieser Tabelle darstellt. Verwenden Sie Anmerkungen, um die Entität und dazugehörige Attribute einer Tabelle und ihren Spalten zuzuordnen.

Sie können die folgenden Annotationen verwenden, um einfache Beziehungen zwischen Entitäten und Tabellen zu modellieren:

Entitätsanmerkungen
@Column(name = "columnName")

Optional. Ordnet das Attribut einer bestimmten Spalte in der Spanner-Tabelle zu und überschreibt dabei die Benennungsstrategie, bei der die Namen automatisch zugeordnet werden.

Wenn Sie dieses Attribut weglassen, ordnet die Standard-Benennungsstrategie für Spring Data Spanner die Java-Attributnamen camelCase den Spaltennamen PascalCase zu. Beispiel: Das Attribut singerId entspricht dem Spaltennamen SingerId.

@Embedded

Gibt an, dass das Attribut ein eingebettetes Objekt ist, das Komponenten eines Primärschlüssels enthalten kann. Wenn das Attribut tatsächlich im Primärschlüssel verwendet wird, müssen Sie auch die Anmerkung @PrimaryKey angeben.

@Interleaved

@Interleaved(lazy = true)

Gibt an, dass ein Attribut eine Liste von Zeilen enthält, die mit der aktuellen Zeile verschränkt sind.

Standardmäßig ruft Spring Data Spanner die verschränkten Zeilen bei der Instanzerstellung ab. Zum verzögerten Abruf der Zeilen verwenden Sie @Interleaved(lazy = true), wenn Sie auf das Attribut zugreifen.

Beispiel: Wenn die Entität Singer verschränkte Album-Einträge als untergeordnete Elemente haben kann, fügen Sie der Entität Singer das Attribut List<Album> hinzu. Fügen Sie außerdem dem Attribut die Anmerkung @Interleaved hinzu.

@NotMapped

Gibt an, dass ein Attribut nicht in der Datenbank gespeichert ist und ignoriert werden sollte.

@PrimaryKey

@PrimaryKey(keyOrder = N)

Gibt an, dass das Attribut eine Komponente des Primärschlüssels ist und die Position des Attributs innerhalb des Primärschlüssels angibt, beginnend bei 1. Der Standardwert von keyOrder ist 1.

Beispiel: @PrimaryKey(keyOrder = 3)

@Table(name = "TABLE_NAME")

Die Tabelle, die die Entität modelliert. Jede Instanz der Entität stellt einen Datensatz in der Tabelle dar. Ersetzen Sie TABLE_NAME durch den Namen Ihrer Tabelle.

Beispiel: @Table(name = "Singers")

Wenn Sie komplexere Beziehungen modellieren müssen, finden Sie in der Referenz zu Spring Data Spanner weitere Informationen zu anderen Annotationen, die das Modul unterstützt.

Die folgenden Beispiele zeigen eine Möglichkeit, die Tabellen Singers und Albums für Spring Data Spanner zu modellieren:

  • Für Singer-Entitäten enthält das Beispiel das Attribut albums mit der Anmerkung @Interleaved. Dieses Attribut enthält eine Liste von Alben, die mit der Entität Singer verschränkt sind. Spring Data Spanner füllt diese Eigenschaft automatisch aus.
  • Für Album-Entitäten enthält das Beispiel das Attribut relatedAlbums, das nicht in Spanner gespeichert ist.
import com.google.cloud.spring.data.spanner.core.mapping.Interleaved;
import com.google.cloud.spring.data.spanner.core.mapping.PrimaryKey;
import com.google.cloud.spring.data.spanner.core.mapping.Table;
import java.util.Date;
import java.util.List;

/**
 * An entity and table holding singers.
 */
@Table(name = "Singers")
public class Singer {
  @PrimaryKey
  long singerId;

  String firstName;

  String lastName;

  Date birthDate;

  @Interleaved
  List<Album> albums;
}
import com.google.cloud.spring.data.spanner.core.mapping.NotMapped;
import com.google.cloud.spring.data.spanner.core.mapping.PrimaryKey;
import com.google.cloud.spring.data.spanner.core.mapping.Table;
import java.util.List;

/**
 * An entity class representing an Album.
 */
@Table(name = "Albums")
public class Album {

  @PrimaryKey
  long singerId;

  @PrimaryKey(keyOrder = 2)
  long albumId;

  String albumTitle;

  long marketingBudget;

  @NotMapped
  List<Album> relatedAlbums;

  public Album(long singerId, long albumId, String albumTitle, long marketingBudget) {
    this.singerId = singerId;
    this.albumId = albumId;
    this.albumTitle = albumTitle;
    this.marketingBudget = marketingBudget;
  }
}

Daten abfragen und ändern

Wenn Sie Daten mit Spring Data Spanner abfragen und ändern möchten, können Sie eine SpannerTemplate-Bean übernehmen, die SpannerOperations implementiert. SpannerTemplate bietet Methoden zum Durchführen von SQL-Abfragen und Ändern von Daten mit DML-Anweisungen (Data Manipulation Language). Sie können diese Bean auch verwenden, um auf die Read API und die Mutation API für Spanner zuzugreifen.

Darüber hinaus können Sie die SpannerRepository-Schnittstelle erweitern, um die gesamte Anwendungslogik zu kapseln, die Daten in Spanner abfragt und ändert.

In den folgenden Abschnitten wird die Verwendung von SpannerTemplate und SpannerRepository erläutert.

Vorlagen-Bean erwerben

Mit der Anmerkung @Autowired können Sie eine SpannerTemplate-Bean automatisch übernehmen. Anschließend können Sie SpannerTemplate in der gesamten Klasse verwenden.

Das folgende Beispiel zeigt eine Klasse, die die Bean übernimmt und verwendet:

import com.google.cloud.spanner.KeySet;
import com.google.cloud.spanner.Statement;
import com.google.cloud.spring.data.spanner.core.SpannerQueryOptions;
import com.google.cloud.spring.data.spanner.core.SpannerTemplate;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * A quick start code for Spring Data Cloud Spanner. It demonstrates how to use SpannerTemplate to
 * execute DML and SQL queries, save POJOs, and read entities.
 */
@Component
public class SpannerTemplateSample {

  @Autowired
  SpannerTemplate spannerTemplate;

  public void runTemplateExample(Singer singer) {
    // Delete all of the rows in the Singer table.
    this.spannerTemplate.delete(Singer.class, KeySet.all());

    // Insert a singer into the Singers table.
    this.spannerTemplate.insert(singer);

    // Read all of the singers in the Singers table.
    List<Singer> allSingers = this.spannerTemplate
        .query(Singer.class, Statement.of("SELECT * FROM Singers"),
                new SpannerQueryOptions().setAllowPartialRead(true));
  }

}

Sie können die SpannerTemplate-Bean verwenden, um nur schreibgeschützte Transaktionen und Lese-Schreib-Transaktionen auszuführen. Außerdem können Sie die @Transactional-Anmerkung verwenden, um deklarative Transaktionen zu erstellen.

Repository-Bean erwerben

Bei Verwendung eines SpannerRepository können Sie die @Autowired-Anmerkung zur Übernahme einer Bean verwenden, die die Oberfläche Ihres Repositorys implementiert. Ein Repository enthält Methoden zum Ausführen von Java-Funktionen als schreibgeschützte Transaktionen und Lese-Schreib-Transaktionen. Für untergeordnete Vorgänge können Sie die vom Repository verwendete Vorlagen-Bean abrufen.

Die folgenden Beispiele zeigen die Oberfläche für ein Repository und eine Klasse, die die Bean übernimmt und verwendet:

import com.google.cloud.spanner.Key;
import com.google.cloud.spring.data.spanner.repository.SpannerRepository;
import com.google.cloud.spring.data.spanner.repository.query.Query;
import java.util.List;
import org.springframework.data.repository.query.Param;

/**
 * An interface of various Query Methods. The behavior of the queries is defined only by
 * their names, arguments, or annotated SQL strings. The implementation of these functions
 * is generated by Spring Data Cloud Spanner.
 */
public interface SingerRepository extends SpannerRepository<Singer, Key> {
  List<Singer> findByLastName(String lastName);

  int countByFirstName(String firstName);

  int deleteByLastName(String lastName);

  List<Singer> findTop3DistinctByFirstNameAndSingerIdIgnoreCaseOrLastNameOrderByLastNameDesc(
      String firstName, String lastName, long singerId);

  @Query("SELECT * FROM Singers WHERE firstName LIKE '%@fragment';")
  List<Singer> getByQuery(@Param("fragment") String firstNameFragment);
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * A quick start code for Spring Data Cloud Spanner.
 * It demonstrates how to use a SpannerRepository to execute read-write queries
 * generated from interface definitions.
 *
 */
@Component
public class SpannerRepositorySample {

  @Autowired
  SingerRepository singerRepository;

  public void runRepositoryExample() {
    List<Singer> lastNameSingers = this.singerRepository.findByLastName("a last name");

    int fistNameCount = this.singerRepository.countByFirstName("a first name");

    int deletedLastNameCount = this.singerRepository.deleteByLastName("a last name");
  }

}

Spanner verwalten

Wenn Sie Informationen zu Ihren Spanner-Datenbanken abrufen, ein Schema mit einer DDL-Anweisung (Data Definition Language) aktualisieren oder andere Verwaltungsaufgaben ausführen möchten, können Sie eine SpannerDatabaseAdminTemplate-Bean übernehmen.

Mit der Anmerkung @Autowired können Sie eine -Bean automatisch übernehmen. Anschließend können Sie die SpannerDatabaseAdminTemplate in der gesamten Klasse verwenden.

Das folgende Beispiel zeigt eine Klasse, die die Bean übernimmt und verwendet:

import com.google.cloud.spring.data.spanner.core.admin.SpannerDatabaseAdminTemplate;
import com.google.cloud.spring.data.spanner.core.admin.SpannerSchemaUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * This sample demonstrates how to generate schemas for interleaved tables from POJOs and how to
 * execute DDL.
 */
@Component
public class SpannerSchemaToolsSample {

  @Autowired
  SpannerDatabaseAdminTemplate spannerDatabaseAdminTemplate;

  @Autowired
  SpannerSchemaUtils spannerSchemaUtils;

  /**
   * Creates the Singers table. Also creates the Albums table, because Albums is interleaved with
   * Singers.
   */
  public void createTableIfNotExists() {
    if (!this.spannerDatabaseAdminTemplate.tableExists("Singers")) {
      this.spannerDatabaseAdminTemplate.executeDdlStrings(
          this.spannerSchemaUtils
              .getCreateTableDdlStringsForInterleavedHierarchy(Singer.class),
          true);
    }
  }

  /**
   * Drops both the Singers and Albums tables using just a reference to the Singer entity type ,
   * because they are interleaved.
   */
  public void dropTables() {
    if (this.spannerDatabaseAdminTemplate.tableExists("Singers")) {
      this.spannerDatabaseAdminTemplate.executeDdlStrings(
          this.spannerSchemaUtils.getDropTableDdlStringsForInterleavedHierarchy(Singer.class),
          false);
    }
  }
}

Nächste Schritte