Spring Boot-Anwendung mit Cloud Spanner

1. Übersicht

Cloud Spanner ist ein hochverfügbares, horizontal skalierbares und multiregionales RDBMS. In diesem Codelab wird eine kleinste Instanz von Cloud Spanner verwendet. Vergessen Sie jedoch nicht, sie wieder herunterzufahren, wenn Sie fertig sind.

Aufgaben in diesem Lab

  • Cloud Spanner zum Speichern und Abrufen von Daten mit Spring Boot verwenden

Voraussetzungen

  • Google Cloud Platform-Projekt
  • Ein Browser, z. B. Chrome oder Firefox

Wie möchten Sie diese Anleitung nutzen?

<ph type="x-smartling-placeholder"></ph> Nur bis zum Ende lesen Lies sie dir durch und absolviere die Übungen

Wie würden Sie Ihre Erfahrungen im Umgang mit Google Cloud Platform-Diensten bewerten?

<ph type="x-smartling-placeholder"></ph> Neuling Mittel Kompetent

2. Einrichtung und Anforderungen

Umgebung für das selbstbestimmte Lernen einrichten

  1. Melden Sie sich in der Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder G Suite-Konto haben, müssen Sie ein Konto erstellen.

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

Notieren Sie sich die Projekt-ID, also den projektübergreifend nur einmal vorkommenden Namen eines Google Cloud-Projekts. Der oben angegebene Name ist bereits vergeben und kann leider nicht mehr verwendet werden. Sie wird in diesem Codelab später als PROJECT_ID bezeichnet.

  1. Als Nächstes müssen Sie in der Cloud Console die Abrechnung aktivieren, um Google Cloud-Ressourcen nutzen zu können.

Dieses Codelab sollte ohne großen Aufwand betrieben werden. Folgen Sie der Anleitung im Abschnitt „Bereinigen“, . Hier erfahren Sie, wie Sie Ressourcen herunterfahren, damit Ihnen über dieses Tutorial hinaus keine Kosten entstehen. Neue Google Cloud-Nutzer können an der kostenlosen Testversion von 300$ teilnehmen.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren H7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtZWQFrF.

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

Wenn Sie Cloud Shell zum ersten Mal verwenden, wird ein Zwischenbildschirm (below the fold) angezeigt, in dem beschrieben wird, worum es sich dabei handelt. Klicken Sie in diesem Fall auf Weiter. Der Chat wird nie wieder angezeigt. So sieht dieser einmalige Bildschirm aus:

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

Die Bereitstellung und Verbindung mit Cloud Shell dauert nur einen Moment.

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

Diese virtuelle Maschine verfügt über sämtliche Entwicklertools, die Sie benötigen. Es bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und wird in Google Cloud ausgeführt. Dadurch werden die Netzwerkleistung und die Authentifizierung erheblich verbessert. Viele, wenn nicht sogar alle Arbeiten in diesem Codelab können Sie ganz einfach mit einem Browser oder Ihrem Chromebook erledigen.

Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie bereits authentifiziert sind und dass das Projekt bereits auf Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

3. Cloud Spanner initialisieren

Aktivieren Sie die Cloud Spanner API mithilfe der gcloud CLI:

gcloud services enable spanner.googleapis.com

Erstellen Sie eine Cloud Spanner-Instanz:

gcloud spanner instances create spanner-instance \
 --config=regional-us-central1 \
 --nodes=1 --description="A Spanner Instance"

Erstellen Sie eine Datenbank in der Instanz:

gcloud spanner databases create orders \
  --instance=spanner-instance

Erstellen Sie eine schema.ddl-Datei, um das Datenschema zu beschreiben:

cat << EOF > schema.ddl
CREATE TABLE orders (
  order_id STRING(36) NOT NULL,
  description STRING(255),
  creation_timestamp TIMESTAMP,
) PRIMARY KEY (order_id);

CREATE TABLE order_items (
  order_id STRING(36) NOT NULL,
  order_item_id STRING(36) NOT NULL,
  description STRING(255),
  quantity INT64,
) PRIMARY KEY (order_id, order_item_id),
  INTERLEAVE IN PARENT orders ON DELETE CASCADE;
EOF

Wenden Sie das Schema auf die Cloud Spanner-Datenbank an:

gcloud spanner databases ddl update orders \
  --instance=spanner-instance \
  --ddl="$(<schema.ddl)"

4. Neue Spring Boot-Java-Anwendung bootstrappen

Führen Sie in der Cloud Shell-Umgebung den folgenden Befehl aus, um eine neue Spring Boot-Anwendung zu initialisieren und das Bootstrapping durchzuführen:

$ curl https://start.spring.io/starter.tgz \
  -d packaging=jar \
  -d dependencies=cloud-gcp,web,lombok \
  -d baseDir=spanner-example \
  -d type=maven-project \
  -d bootVersion=3.2.6 | tar -xzvf -

$ cd spanner-example

Dadurch wird ein neues spanner-example/-Verzeichnis mit einem neuen Maven-Projekt, zusammen mit der pom.xml von Maven, einem Maven-Wrapper und einem Anwendungseinstiegspunkt erstellt.

Fügen Sie in der Datei pom.xml den Spring Data Cloud Spanner-Auslöser hinzu.

spanner-beispiel/pom.xml

<project>
  ...
  <dependencies>
        ...
        <!-- Add Spring Cloud GCP Spanner Starter -->
        <dependency>
                <groupId>com.google.cloud</groupId>
                <artifactId>spring-cloud-gcp-starter-data-spanner</artifactId>
        </dependency>

        ...

  </dependencies>

  ...
</project>

Konfigurieren Sie in „application.properties“ die Informationen zur Spanner-Datenbankverbindung:

spanner-example/src/main/resources/application.properties

spring.cloud.gcp.spanner.instance-id=spanner-instance
spring.cloud.gcp.spanner.database=orders

Prüfen Sie, ob JAVA_HOME auf die richtige Version eingestellt ist:

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/

Erstellen Sie die App neu, um sicherzustellen, dass Ihre Maven-Konfiguration korrekt ist:

./mvnw package

5. Entitäten erstellen

Mit der Spring Data Spanner-Unterstützung von Spring Cloud GCP können Sie mithilfe von Spring Data auf einfache Weise ein Java-Objekt und eine idiomatische ORM-Zuordnung zu einer Spanner-Tabelle erstellen.

Erstellen Sie zuerst eine Klasse für das Bestellelement.

spanner-example/src/main/java/com/example/demo/OrderItem.java

package com.example.demo;

import com.google.cloud.spring.data.spanner.core.mapping.Column;
import com.google.cloud.spring.data.spanner.core.mapping.PrimaryKey;
import com.google.cloud.spring.data.spanner.core.mapping.Table;

@Table(name="order_items")
@Data
class OrderItem {
  @PrimaryKey(keyOrder = 1)
  @Column(name="order_id")
  private String orderId;

  @PrimaryKey(keyOrder = 2)
  @Column(name="order_item_id")
  private String orderItemId;

  private String description;
  private Long quantity;
}

Für über-/untergeordnete Beziehungen in Spanner sollten Sie einen zusammengesetzten Primärschlüssel verwenden. In diesem Beispiel sind order_id und order_item_id der zusammengesetzte Schlüssel.

Erstellen Sie als Nächstes eine Order-Klasse:

spanner-example/src/main/java/com/example/demo/Order.java

package com.example.demo;

import java.time.LocalDateTime;
import java.util.List;
import lombok.Data;
import com.google.cloud.spring.data.spanner.core.mapping.Column;
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;

@Table(name="orders")
@Data
public class Order {
  @PrimaryKey
  @Column(name="order_id")
  private String id;

  private String description;

  @Column(name="creation_timestamp")
  private LocalDateTime timestamp;

  @Interleaved
  private List<OrderItem> items;
}

Diese Klasse verwendet die Anmerkung @Interleaved, um eine 1:n-Beziehung mit Bestellelementen zu erstellen.

6. OrderRepository-Oberfläche erstellen

Erstellen Sie die Klasse OrderRepository mit folgendem Inhalt:

spanner-example/src/main/java/com/example/demo/OrderRepository.java

package com.example.demo;

import com.google.cloud.spring.data.spanner.repository.SpannerRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface OrderRepository extends SpannerRepository<Order, String> {
}

Die Schnittstelle erweitert SpannerRepository<Order, String>, wobei Order die Domainklasse und String der Typ des Primärschlüssels ist. Spring Data bietet automatisch CRUD-Zugriff über diese Schnittstelle und Sie müssen keinen zusätzlichen Code erstellen.

7. REST-Controller für grundlegende Vorgänge erstellen

Öffnen Sie die DemoApplication-Hauptklasse der Anwendung und ändern Sie sie so:

spanner-example/src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

import java.time.LocalDateTime;
import java.util.UUID;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

@SpringBootApplication
public class DemoApplication {
        public static void main(String[] args) {
                SpringApplication.run(DemoApplication.class, args);
        }
}

@RestController
class OrderController {
  private final OrderRepository orderRepository;

        OrderController(OrderRepository orderRepository) {
                this.orderRepository = orderRepository;
        }

        @GetMapping("/api/orders/{id}")
        public Order getOrder(@PathVariable String id) {
          return orderRepository.findById(id)
                                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, id + " not found"));
        }

        @PostMapping("/api/orders")
        public String createOrder(@RequestBody Order order) {
                // Spanner currently does not auto generate IDs
                // Generate UUID on new orders
                order.setId(UUID.randomUUID().toString());
                order.setTimestamp(LocalDateTime.now());

                order.getItems().forEach(item -> {
                        // Assign parent ID, and also generate child ID
                        item.setOrderId(order.getId());
                        item.setOrderItemId(UUID.randomUUID().toString());
                });

          Order saved = orderRepository.save(order);
          return saved.getId();
        }
}

8. Anwendung ausführen

Erstellen Sie die Anwendung neu und führen Sie sie aus.

./mvnw spring-boot:run

Dies sollte ordnungsgemäß starten und Port 8080 überwachen.

Sie können einen Auftragsdatensatz an den Endpunkt senden:

curl -H"Content-Type: application/json" -d'{"description": "My orders", "items": [{"description": "Android Phone", "quantity": "1"}]}' \
  http://localhost:8080/api/orders

Sie sollte mit der UUID der Bestellung antworten.

Anschließend können Sie die Bestellung mit dem UUID abrufen:

curl http://localhost:8080/api/orders/REPLACE_WITH_ORDER_UUID

Wenn Sie sehen möchten, wie die Daten in Cloud Spanner gespeichert werden, rufen Sie die Cloud Console auf und gehen Sie zu Spanner → Spanner-Instanz → Bestelldatenbank → Tabelle mit Bestellungen → Daten.

780f4947e4a864f6.png

9. Bereinigen

Löschen Sie zum Bereinigen die Spanner-Instanz, damit keine Gebühren mehr anfallen.

gcloud spanner instances delete spanner-instance -q

10. Glückwunsch!

In diesem Codelab haben Sie eine interaktive Befehlszeilenanwendung erstellt, mit der Sie Daten in Cloud Spanner speichern und abrufen können.

Weitere Informationen

Lizenz

Dieser Text ist mit einer Creative Commons Attribution 2.0 Generic License lizenziert.