Spring Boot-Anwendung mit Cloud Datastore

1. Übersicht

Google Cloud Datastore ist eine NoSQL-Dokumentdatenbank, die auf automatische Skalierung, hohe Leistung und einfache Anwendungsentwicklung ausgelegt ist.

Lerninhalte

  • Cloud Datastore zum Speichern und Abrufen von Java-Objekten in Spring Boot verwenden

Voraussetzungen

Wie werden Sie diese Anleitung verwenden?

Nur lesen Lesen und Übungen durchführen

Wie würden Sie Ihre Erfahrungen mit der Verwendung von Google Cloud Platform-Diensten bewerten?

Anfänger Mittelstufe Fortgeschritten

2. Einrichtung und Anforderungen

Umgebung zum selbstbestimmten Lernen einrichten

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

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Es handelt sich um einen String, der nicht von Google APIs verwendet wird. Sie können sie jederzeit aktualisieren.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich (kann nach dem Festlegen nicht mehr geändert werden). In der Cloud Console wird automatisch ein eindeutiger String generiert. Normalerweise ist es nicht wichtig, wie dieser String aussieht. In den meisten Codelabs müssen Sie auf Ihre Projekt-ID verweisen (in der Regel als PROJECT_ID angegeben). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige ID generieren. Alternativ können Sie es mit einem eigenen Namen versuchen und sehen, ob er verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen.
  • Zur Information: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten
  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/-APIs zu verwenden. Die Durchführung dieses Codelabs kostet wenig oder gar nichts. Wenn Sie Ressourcen herunterfahren möchten, um Kosten zu vermeiden, die über diese Anleitung hinausgehen, können Sie die erstellten Ressourcen oder das Projekt löschen. Neue Google Cloud-Nutzer können am kostenlosen Testzeitraum mit einem Guthaben von 300$ teilnehmen.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Wenn Sie die Cloud Shell zum ersten Mal starten, wird ein Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall einfach auf Weiter.

9c92662c6a846a5c.png

Das Herstellen der Verbindung mit der Cloud Shell sollte nur wenige Augenblicke dauern.

9f0e51b578fecce5.png

Auf dieser virtuellen Maschine sind alle erforderlichen Entwicklungstools installiert. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Die meisten, wenn nicht sogar alle Aufgaben in diesem Codelab können mit einem Browser erledigt werden.

Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie authentifiziert sind und für das Projekt Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in der 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`
  1. Führen Sie den folgenden Befehl in Cloud Shell aus, um zu bestätigen, dass der gcloud-Befehl Ihr Projekt kennt:
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 Datastore initialisieren

Rufen Sie in der GCP Console das Menü > Datastore (im Bereich „Speicher“) auf oder klicken Sie hier.

Wenn Sie Datastore im aktuellen Projekt noch nie verwendet haben, wird der Bildschirm Cloud Firestore-Modus auswählen angezeigt. Wählen Sie die Option Datastore-Modus aus.

f938295c7ff297f4.png

Danach wird der Bildschirm Speicherort für Daten auswählen angezeigt. Wählen Sie us-east1 oder einen anderen regionalen Standort aus und klicken Sie auf „Datenbank erstellen“:

916ac84fec10fae7.png

4. Neue Spring Boot-Java-Anwendung booten

Verwenden Sie in der Cloud Shell-Umgebung den folgenden Befehl, um eine neue Spring Boot-Anwendung zu initialisieren und zu booten:

$ curl https://start.spring.io/starter.tgz \
  -d packaging=war \
  -d dependencies=cloud-gcp \
  -d type=maven-project \
  -d baseDir=datastore-example \
  -d bootVersion=3.0.5 | tar -xzvf -

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

Unsere Anwendung bietet eine Befehlszeilenschnittstelle, über die Nutzer Befehle eingeben und Ergebnisse sehen können. Wir erstellen eine Klasse, die ein Buch repräsentiert, und speichern sie dann mit dem Datastore-Repository in Cloud Datastore.

Außerdem müssen wir dem pom.xml eine weitere erforderliche Abhängigkeit hinzufügen.

Öffnen Sie den Webcode-Editor, indem Sie im Cloud Shell-Menü auf Editor öffnen klicken.

6d823258c76a7452.png

Nachdem der Editor geladen wurde, ändern Sie die Datei pom.xml, um die Abhängigkeiten „Google Cloud Datastore Starter“ und „Spring Shell Starter“ hinzuzufügen:

pom.xml

<project>
  ...
  <dependencies>
        ...
        <!-- Add GCP Datastore Starter -->
        <dependency>
                <groupId>com.google.cloud</groupId>
                <artifactId>spring-cloud-gcp-starter-data-datastore</artifactId>
        </dependency>

        <!-- Add Spring Shell Starter -->
        <dependency>
                <groupId>org.springframework.shell</groupId>
                <artifactId>spring-shell-starter</artifactId>
                <version>3.0.2</version>
        </dependency>

  </dependencies>
</project>

5. Klasse „Book“ erstellen

Erstellen Sie mit dem Editor die Klasse Book mit folgendem Inhalt:

datastore-example/src/main/java/com/example/demo/Book.java

package com.example.demo;

import com.google.cloud.spring.data.datastore.core.mapping.Entity;
import org.springframework.data.annotation.Id;

@Entity(name = "books")
public class Book {
  @Id
  Long id;

  String title;

  String author;

  int year;

  public Book(String title, String author, int year) {
    this.title = title;
    this.author = author;
    this.year = year;
  }

  public long getId() {
    return this.id;
  }

  @Override
  public String toString() {
    return "Book{" +
        "id=" + this.id +
        ", title='" + this.title + '\'' +
        ", author='" + this.author + '\'' +
        ", year=" + this.year +
        '}';
  }
}

Wie Sie sehen, handelt es sich um ein einfaches POJO. Die Klasse ist mit @Entity annotiert, um anzugeben, dass sie in Datastore gespeichert werden kann, und um den Typnamen anzugeben (ein Typ entspricht einer Tabelle in SQL-Datenbanken, weitere Informationen finden Sie in der Dokumentation). Der Name der Art ist optional. Wenn er weggelassen wird, wird er anhand des Klassennamens generiert.

Wir haben das Attribut id mit @Id annotiert. Das bedeutet, dass dieses Feld als Identifikator für den Datastore-Schlüssel verwendet werden soll. Jede Datastore-Entität benötigt eine Kennung. Unterstützte Typen sind String und Long.

Wir überschreiben die toString-Methode, um die Stringdarstellung der Objekte lesbarer zu machen. Das ist nützlich, wenn wir sie ausgeben.

6. BookRepository-Schnittstelle erstellen

Erstellen Sie die BookRepository-Klasse mit folgendem Inhalt:

datastore-example/src/main/java/com/example/demo/BookRepository.java

package com.example.demo;

import java.util.List;

import com.google.cloud.spring.data.datastore.repository.DatastoreRepository;


public interface BookRepository extends DatastoreRepository<Book, Long> {

  List<Book> findByAuthor(String author);

  List<Book> findByYearGreaterThan(int year);

  List<Book> findByAuthorAndYear(String author, int year);
}

Die Schnittstelle erweitert DatastoreRepository<Book, Long>, wobei Book die Domain-Klasse und Long der Id-Typ ist. Wir deklarieren drei Abfragemethoden in unserem Repository, für die Implementierungen automatisch im Hintergrund generiert werden.

Die erste ist findByAuthor. Wie Sie sich sicher denken können, wird bei der Implementierung dieser Methode eine Abfrage ausgeführt, bei der ein vom Nutzer bereitgestellter Wert im Bedingungsfilter für die Gleichheit mit dem Feld „Autor“ verwendet wird.

Mit der Methode findByYearGreaterThan wird eine Abfrage ausgeführt, die nach dem Feld „year“ (Jahr) filtert, das größer als der vom Nutzer angegebene Wert ist.

findByAuthorAndYear führt eine Abfrage aus, in der nach Einheiten gesucht wird, deren Felder „Autor“ und „Jahr“ mit den vom Nutzer angegebenen Werten übereinstimmen.

7. Interaktive CLI-Anwendung erstellen

Öffnen Sie die Hauptanwendungsklasse DemoApplication und ändern Sie sie so, dass sie so aussieht:

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

package com.example.demo;

import java.util.List;

import com.google.common.collect.Lists;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;

@ShellComponent
@SpringBootApplication
public class DemoApplication {
  @Autowired
  BookRepository bookRepository;

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

  @ShellMethod("Saves a book to Cloud Datastore: save-book <title> <author> <year>")
  public String saveBook(String title, String author, int year) {
     Book savedBook = this.bookRepository.save(new Book(title, author, year));
     return savedBook.toString();
  }

  @ShellMethod("Loads all books")
  public String findAllBooks() {
     Iterable<Book> books = this.bookRepository.findAll();
     return Lists.newArrayList(books).toString();
  }

  @ShellMethod("Loads books by author: find-by-author <author>")
  public String findByAuthor(String author) {
     List<Book> books = this.bookRepository.findByAuthor(author);
     return books.toString();
  }

  @ShellMethod("Loads books published after a given year: find-by-year-after <year>")
  public String findByYearAfter(int year) {
     List<Book> books = this.bookRepository.findByYearGreaterThan(year);
     return books.toString();
  }

  @ShellMethod("Loads books by author and year: find-by-author-year <author> <year>")
  public String findByAuthorYear(String author, int year) {
     List<Book> books = this.bookRepository.findByAuthorAndYear(author, year);
     return books.toString();
  }

  @ShellMethod("Removes all books")
  public void removeAllBooks() {
     this.bookRepository.deleteAll();
  }
}

Beachten Sie, dass wir die Klasse mit @ShellComponent annotiert haben. Dadurch wird Spring mitgeteilt, dass wir diese Klasse als Quelle für CLI-Befehle verwenden möchten. Die mit @ShellMethod gekennzeichneten Methoden werden als CLI-Befehle in unserer Anwendung verfügbar gemacht.

Hier verwenden wir die Methoden, die wir in der BookRepository-Schnittstelle deklariert haben: findByAuthor, findByYearGreaterThan, findByAuthorAndYear. Außerdem verwenden wir drei integrierte Methoden: save, findAll und deleteAll.

Sehen wir uns die Methode saveBook an. Wir erstellen ein Book-Objekt mit den vom Nutzer angegebenen Werten für Titel, Autor und Jahr. Wie Sie sehen, geben wir keinen id-Wert an. Er wird daher beim Speichern automatisch dem Feld id zugewiesen. Die Methode save akzeptiert ein Objekt vom Typ Book und speichert es in Cloud Datastore. Es wird ein Book-Objekt mit allen ausgefüllten Feldern zurückgegeben, einschließlich des Felds id. Am Ende geben wir eine Stringdarstellung dieses Objekts zurück.

Die restlichen Methoden funktionieren ähnlich: Sie akzeptieren übergebene Parameter für die entsprechenden Repository-Methoden und geben stringifizierte Ergebnisse zurück.

8. Anwendung ausführen

Bevor Sie die Anwendung erstellen und starten, müssen Sie prüfen, ob JAVA_HOME auf die richtige Version festgelegt ist:

$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Führen Sie diesen Befehl in Cloud Shell aus (im Stammverzeichnis des Projekts datastore-example/, in dem sich pom.xml befindet):

$ ./mvnw spring-boot:run
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Nach einer erfolgreichen Build-Phase wird das Spring-Logo angezeigt und die Shell-Eingabeaufforderung erscheint:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.5)



shell:>

Jetzt können Sie die zuvor definierten Befehle ausprobieren. Mit dem folgenden Befehl können Sie sich die Liste der Befehle ansehen:

shell:> help
...
find-all-books: Loads all books
find-by-author: Loads books by author: find-by-author <author>
find-by-author-year: Loads books by author and year: find-by-author-year <author> <year>
find-by-year-after: Loads books published after a given year: find-by-year-after <year>
remove-all-books: Removes all books
save-book: Saves a book to Cloud Datastore: save-book <title> <author> <year>

Geben Sie Folgendes ein:

  1. Erstellen Sie einige Bücher mit dem Befehl save-book.
  2. Mit dem Befehl find-all-books suchen
  3. Bücher eines bestimmten Autors finden: find-by-author <author>
  4. Suche nach Büchern, die nach einem bestimmten Jahr veröffentlicht wurden: find-by-year-after <year>
  5. Bücher eines bestimmten Autors und aus einem bestimmten Jahr finden: find-by-author-year <author> <year>

9. Mit der Weboberfläche sehen, was in Datastore gespeichert ist

Wenn Sie sehen möchten, wie die Entitäten in Cloud Datastore gespeichert werden, rufen Sie die GCP Console auf. Geben Sie bei Bedarf „books“ (Bücher) in das Feld „kind“ (Art) ein.

5fab21a6c89f45a.png

10. Bereinigen

Entfernen Sie zum Bereinigen alle Bücher mit dem Befehl remove-all-books aus der Anwendungsshell.

shell:> remove-all-books

Verwenden Sie zum Beenden der Anwendung den Befehl „quit“ und dann Ctrl+C.

11. Glückwunsch!

In diesem Codelab haben Sie eine interaktive CLI-Anwendung erstellt, mit der Objekte in Cloud Datastore gespeichert und abgerufen werden können.

Weitere Informationen

Lizenz

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