Ajouter le module Spring Data Cloud Spanner à une application

Le module Spring Data Cloud Spanner vous aide à utiliser Cloud Spanner dans n'importe quelle application Java conçue avec le framework Spring.

Comme tous les modules Spring Data, Spring Data Cloud Spanner propose un modèle de programmation basé sur Spring qui conserve les garanties de cohérence et l'évolutivité de Cloud Spanner. Ses fonctionnalités sont semblables à celles de Spring Data JPA et Hibernate ORM, avec des annotations conçues pour Cloud Spanner.

Si vous connaissez déjà bien Spring, Spring Data Cloud Spanner peut faciliter l'utilisation de Cloud Spanner dans votre application et réduire la quantité de code à rédiger.

Cette page explique comment ajouter Spring Data Cloud Spanner à une application Java. Pour obtenir des informations détaillées sur le module, consultez la documentation de référence sur Spring Data Cloud Spanner.

Installer le module

Si vous utilisez Maven, ajoutez la nomenclature BOM GCP Spring Cloud et Spring Data Cloud Spanner à votre fichier pom.xml. Ces dépendances fournissent les composants Spring Data Cloud Spanner à votre ApplicationContext Spring :

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-gcp-dependencies</artifactId>
      <version>1.2.4.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-gcp-starter-data-spanner</artifactId>
  </dependency>
</dependencies>

Vous devez également créer un compte de service et utiliser la clé de compte de service pour vous authentifier avec Google Cloud.

Pour plus d'informations, consultez les instructions sur la configuration d'un environnement de développement Java. Vous n'avez pas besoin d'installer la bibliothèque cliente Google Cloud pour Java, Spring Boot s'en charge automatiquement au démarrage.

Configurer le module

Dans cette section, nous allons découvrir certains des paramètres de configuration les plus couramment utilisés pour Spring Data Cloud Spanner. Pour obtenir la liste complète des paramètres, consultez la documentation de référence.

Spécifier une instance et une base de données

Vous devez spécifier l'instance et la base de données Cloud Spanner auxquelles votre application doit se connecter.

Pour spécifier l'instance et la base de données par défaut, définissez les propriétés de configuration suivantes pour votre application :

Valeur Description
spring.cloud.gcp.spanner.project-id Facultatif. ID de projet Google Cloud. Remplace la valeur de spring.cloud.gcp.config.project-id.
spring.cloud.gcp.spanner.instance-id ID d'instance Cloud Spanner.
spring.cloud.gcp.spanner.database Base de données à laquelle se connecter.

Modéliser les données Cloud Spanner

Avec Spring Data Cloud Spanner, vous pouvez utiliser des POJOs (Plain Old Java Object, anciens objets Java standards) pour modéliser les données que vous stockez dans vos tables Cloud Spanner.

Pour chaque table de votre base de données, déclarez une entité qui représente un enregistrement dans cette table. Utilisez des annotations pour mapper l'entité et ses propriétés sur une table et ses colonnes.

Vous pouvez utiliser les annotations suivantes pour modéliser des relations simples entre des entités et des tables :

Annotations d'entités
@Column(name = "columnName")

Facultatif. Mappe la propriété sur une colonne spécifique de la table Cloud Spanner, en remplaçant la stratégie d'attribution de noms automatique.

Lorsque vous omettez cette propriété, la stratégie d'attribution de noms par défaut pour Spring Data Cloud Spanner mappe les noms de propriété camelCase Java aux noms de colonne PascalCase. Par exemple, la propriété singerId correspond au nom de la colonne SingerId.

@Embedded

Indique que la propriété est un objet encapsulé pouvant contenir les composants d'une clé primaire. Si la propriété est réellement utilisée dans la clé primaire, vous devez également inclure l'annotation @PrimaryKey.

@Interleaved

@Interleaved(lazy = true)

Indique qu'une propriété contient une liste de lignes entrelacées dans la ligne actuelle.

Par défaut, Spring Data Cloud Spanner récupère les lignes entrelacées lors de la création de l'instance. Pour récupérer les lignes tardivement, lorsque vous accédez à la propriété, utilisez @Interleaved(lazy = true).

Exemple : Si une entité Singer peut contenir des entrées entrelacées Album en tant qu'enfants, ajoutez une propriété List<Album> à l'entité Singer. Ajoutez également une annotation @Interleaved à la propriété.

@NotMapped

Indique qu'une propriété n'est pas stockée dans la base de données et doit être ignorée.

@PrimaryKey

@PrimaryKey(keyOrder = N)

Indique que la propriété est un composant de la clé primaire et identifie la position de la propriété dans la clé primaire, en partant de 1. La valeur keyOrder par défaut est 1.

Exemple : @PrimaryKey(keyOrder = 3)

@Table(name = "TABLE_NAME")

La table que modélise l'entité. Chaque instance de l'entité représente un enregistrement dans la table. Remplacez TABLE_NAME par le nom de votre table.

Exemple : @Table(name = "Singers")

Pour modéliser des relations plus complexes, consultez la documentation de référence sur Spring Data Cloud Spanner pour en savoir plus sur les autres annotations compatibles avec le module.

Les exemples suivants montrent comment modéliser les tables Singers et Albums pour Spring Data Cloud Spanner :

  • Pour les entités Singer, l'exemple inclut une propriété albums, avec une annotation @Interleaved. Cette propriété contient une liste d'albums entrelacés avec l'entité Singer. Spring Data Cloud Spanner remplit automatiquement cette propriété.
  • Pour les entités Album, l'exemple inclut une propriété relatedAlbums, qui n'est pas stockée dans Cloud Spanner.
import java.util.Date;
import java.util.List;
import org.springframework.cloud.gcp.data.spanner.core.mapping.Embedded;
import org.springframework.cloud.gcp.data.spanner.core.mapping.Interleaved;
import org.springframework.cloud.gcp.data.spanner.core.mapping.PrimaryKey;
import org.springframework.cloud.gcp.data.spanner.core.mapping.Table;

/**
 * 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 java.util.List;
import org.springframework.cloud.gcp.data.spanner.core.mapping.NotMapped;
import org.springframework.cloud.gcp.data.spanner.core.mapping.PrimaryKey;
import org.springframework.cloud.gcp.data.spanner.core.mapping.Table;

/**
 * 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;
  }
}

Interroger et modifier des données

Pour interroger et modifier des données avec Spring Data Cloud Spanner, vous pouvez acquérir un bean SpannerTemplate, qui met en œuvre SpannerOperations. SpannerTemplate fournit des méthodes permettant d'effectuer des requêtes SQL et de modifier des données à l'aide d'instructions LMD (langage de manipulation de données). Ce bean vous permet également d'accéder à l'API de lecture et à l'API Mutation pour Cloud Spanner.

En outre, vous pouvez étendre l'interface SpannerRepository pour qu'elle encapsule l'ensemble de la logique d'application qui interroge et modifie les données dans Cloud Spanner.

Les sections suivantes expliquent comment utiliser SpannerTemplate et SpannerRepository.

Acquérir un modèle de bean

Utilisez l'annotation @Autowired pour acquérir automatiquement un bean SpannerTemplate. Vous pouvez ensuite utiliser SpannerTemplate dans votre classe.

L'exemple suivant illustre l'acquisition et l'utilisation du bean dans une classe :

import com.google.cloud.spanner.KeySet;
import com.google.cloud.spanner.Statement;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gcp.data.spanner.core.SpannerTemplate;
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"), null);
  }

}

Le bean SpannerTemplate permet d'exécuter des transactions en lecture seule et des transactions en lecture/écriture. En outre, l'annotation @Transactional permet de créer des transactions déclaratives.

Acquérir un bean de dépôt

Si vous utilisez un SpannerRepository, vous pouvez vous servir de l'annotation @Autowired pour acquérir un bean qui met en œuvre l'interface de votre dépôt. Un dépôt inclut des méthodes permettant d'exécuter des fonctions Java en tant que transactions en lecture seule et transactions en lecture/écriture. Pour les opérations de niveau inférieur, vous pouvez obtenir le modèle de bean utilisé par le dépôt.

Les exemples suivants montrent l'interface d'un dépôt, ainsi que l'acquisition et l'utilisation du bean dans une classe :

import com.google.cloud.spanner.Key;
import java.util.List;
import org.springframework.cloud.gcp.data.spanner.repository.SpannerRepository;
import org.springframework.cloud.gcp.data.spanner.repository.query.Query;
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");
  }

}

Gérer Cloud Spanner

L'acquisition d'un bean SpannerDatabaseAdminTemplate permet d'obtenir des informations sur vos bases de données Cloud Spanner, de modifier un schéma à l'aide d'une instruction LDD (Data Definition Language, langage de définition de données) ou d'effectuer d'autres tâches d'administration.

Utilisez l'annotation @Autowired pour acquérir automatiquement le bean. Vous pouvez ensuite utiliser SpannerDatabaseAdminTemplate dans votre classe.

L'exemple suivant illustre l'acquisition et l'utilisation du bean dans une classe :

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gcp.data.spanner.core.admin.SpannerDatabaseAdminTemplate;
import org.springframework.cloud.gcp.data.spanner.core.admin.SpannerSchemaUtils;
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);
    }
  }
}

Étape suivante