Spring Boot-Anwendung mit Cloud Datastore

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

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

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

Einrichtung der Umgebung im eigenen Tempo

Wenn Sie noch kein Google-Konto (Gmail oder Google Apps) haben, müssen Sie eins erstellen. Melden Sie sich in der Google Cloud Platform Console (console.cloud.google.com) an und erstellen Sie ein neues Projekt:

Screenshot vom 10.02.2016, 12:45:26.png

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.

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

Dieses Codelab sollte Sie nicht mehr als ein paar Dollar kosten, aber es könnte mehr sein, wenn Sie sich für mehr Ressourcen entscheiden oder wenn Sie sie laufen lassen (siehe Abschnitt „Bereinigen“ am Ende dieses Dokuments).

Neuen Nutzern der Google Cloud Platform steht eine kostenlose Testversion mit einem Guthaben von 300$ zur Verfügung.

Google Cloud Shell aktivieren

Klicken Sie in der GCP Console oben rechts in der Symbolleiste auf das Cloud Shell-Symbol:

Klicken Sie dann auf "Cloud Shell starten":

Die Bereitstellung und Verbindung mit der Umgebung dauert nur einen Moment:

Diese virtuelle Maschine verfügt über sämtliche Entwicklertools, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft auf der Google Cloud, wodurch Netzwerkleistung und Authentifizierung deutlich verbessert werden. Sie können die meisten, wenn nicht sogar alle Schritte in diesem Lab einfach mit einem Browser oder Ihrem Google Chromebook durchführen.

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

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

gcloud auth list

Befehlsausgabe

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
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].

Rufen Sie in der GCP Console das Menü > Datastore (im Abschnitt „Storage“) auf.

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.

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“:

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 baseDir=datastore-example \
  -d bootVersion=2.1.1.RELEASE | tar -xzvf -

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

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 der pom.xml eine weitere erforderliche Abhängigkeit hinzufügen.

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

Nachdem der Editor geladen wurde, ändern Sie die Datei pom.xml, um die Spring Data Cloud Datastore Spring Boot-Starter-Abhängigkeit hinzuzufügen:

pom.xml

<project>
  ...
  <dependencies>
        ...
        <!-- Add GCP Datastore Starter -->
        <dependency>
                <groupId>org.springframework.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>2.0.0.RELEASE</version>
        </dependency>

  </dependencies>
</project>

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 org.springframework.cloud.gcp.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 kann als Tabelle in SQL-Datenbanken betrachtet werden. 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 die Property 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 Methode toString , um die Stringdarstellung der Objekte lesbarer zu machen. Das ist nützlich, wenn wir sie ausgeben.

Vergessen Sie nicht, die Datei zu speichern.

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 org.springframework.cloud.gcp.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 Domainklasse und Long der Typ Id 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.

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

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

Ö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 automatisch zugewiesen und beim Speichern dem ID-Feld 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.

Führen Sie den folgenden Befehl in Cloud Shell aus (im Stammverzeichnis des Projekts datastore-example/, in dem sich die Datei pom.xml befindet), um die Anwendung zu erstellen und zu starten:

$ mvn spring-boot:run

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

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.1.RELEASE)


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. Suche mit dem Befehl find-all-books ausführen
  3. Bücher eines bestimmten Autors finden (find-by-author <author>)
  4. Bücher finden, 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>)

Wenn Sie sehen möchten, wie die Entitäten in Cloud Datastore gespeichert werden, rufen Sie die GCP Console auf und wählen Sie Menü -> Datastore (im Abschnitt „Storage“) -> Entitäten aus. Wählen Sie bei Bedarf den Namespace „[default]“ und die Art „books“ aus.

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 „Strg+C“.

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.