Приложение Spring Boot с Cloud Datastore

Google Cloud Datastore — это база данных документов NoSQL, созданная для автоматического масштабирования, высокой производительности и простоты разработки приложений.

Чему вы научитесь

  • Как использовать Cloud Datastore для сохранения и извлечения объектов Java в Spring Boot

Что вам понадобится

  • Проект облачной платформы Google
  • Браузер, например Chrome или Firefox

Как вы будете использовать это руководство?

Прочитайте это только до конца Прочитайте и выполните упражнения.

Как бы вы оценили свой опыт использования сервисов Google Cloud Platform?

Новичок Средний Опытный

Настройка среды для самостоятельного обучения

Если у вас ещё нет учётной записи Google (Gmail или Google Apps), необходимо её создать . Войдите в консоль Google Cloud Platform ( console.cloud.google.com ) и создайте новый проект:

Скриншот от 2016-02-10 12:45:26.png

Запомните идентификатор проекта — уникальное имя для всех проектов Google Cloud (имя, указанное выше, уже занято и не будет вам работать, извините!). Далее в этой практической работе он будет обозначаться как PROJECT_ID .

Далее вам необходимо включить биллинг в Cloud Console, чтобы использовать ресурсы Google Cloud.

Выполнение этой лабораторной работы не должно обойтись вам дороже нескольких долларов, но может обойтись дороже, если вы решите использовать больше ресурсов или оставите их запущенными (см. раздел «Очистка» в конце этого документа).

Новые пользователи Google Cloud Platform имеют право на бесплатную пробную версию стоимостью 300 долларов США .

Активировать Google Cloud Shell

В консоли GCP щелкните значок Cloud Shell на верхней правой панели инструментов:

Затем нажмите «Запустить Cloud Shell»:

Подготовка и подключение к среде займет всего несколько минут:

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Она предлагает постоянный домашний каталог объёмом 5 ГБ и работает в облаке Google Cloud, что значительно повышает производительность сети и аутентификацию. Значительную часть работы в этой лаборатории, если не всю, можно выполнить, просто используя браузер или Chromebook от Google.

После подключения к Cloud Shell вы должны увидеть, что вы уже аутентифицированы и что проекту уже присвоен ваш PROJECT_ID .

Выполните следующую команду в Cloud Shell, чтобы подтвердить, что вы прошли аутентификацию:

gcloud auth list

Вывод команды

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Вывод команды

[core]
project = <PROJECT_ID>

Если это не так, вы можете установить его с помощью этой команды:

gcloud config set project <PROJECT_ID>

Вывод команды

Updated property [core/project].

В консоли GCP перейдите в Меню -> Хранилище данных (в разделе Хранилище) .

Если вы никогда не использовали Datastore в текущем проекте, вы увидите экран «Выберите режим Cloud Firestore» . Выберите «Режим Datastore» .

После этого вы увидите экран «Выберите место хранения данных» . Выберите us-east1 или любой другой регион и нажмите «Создать базу данных»:

В среде CloudShell используйте следующую команду для инициализации и загрузки нового приложения Spring Boot:

$ 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 -

Это создаст новый каталог datastore-example/ с новым проектом Maven, а также pom.xml Maven, оболочкой Maven, а также точкой входа приложения.

Наше приложение предоставит пользователям интерфейс командной строки (CLI) для ввода команд и просмотра результатов. Мы создадим класс для представления книги, а затем сохраним его в облачном хранилище данных (Cloud Datastore) с помощью репозитория Datastore.

Нам также необходимо добавить еще одну необходимую зависимость в pom.xml .

Откройте редактор веб-кода, нажав «Запустить редактор кода» в меню Cloud Shell.

После загрузки редактора измените файл pom.xml , чтобы добавить зависимость Spring Data Cloud Datastore Spring Boot starter:

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>

Используя редактор, создайте класс Book со следующим содержимым:

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 +
                                '}';
        }
}

Как видите, это простой POJO-объект. Класс аннотирован @Entity , что указывает на возможность его хранения в Datastore, и предоставляет имя типа (тип можно представить как таблицу в базах данных SQL, подробности см. в документации ). Имя типа необязательно — если оно не указано, оно будет сгенерировано на основе имени класса.

Обратите внимание, что мы аннотировали id свойство с @Id . Это означает, что мы хотим использовать это поле в качестве идентификатора ключа хранилища данных. Каждой сущности хранилища данных необходим идентификатор. Поддерживаемые типы: String и Long .

Мы переопределяем toString метод, позволяющий сделать строковое представление объектов более читабельным; это будет полезно при их распечатке.

Не забудьте сохранить файл!

Создайте класс BookRepository со следующим содержимым:

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);

}

Интерфейс расширяет DatastoreRepository<Book, Long> где Book — это класс домена, а Long — тип Id . В нашем репозитории мы объявляем три метода запросов, реализации которых генерируются автоматически.

Первый — findByAuthor . Как вы можете догадаться, реализация этого метода выполнит запрос, который будет использовать указанное пользователем значение в фильтре условия равенства полю «автор».

Метод findByYearGreaterThan выполняет запрос, который фильтрует поле года, превышающее указанное пользователем значение.

findByAuthorAndYear выполняет запрос, который ищет сущности, в которых поля автора и года соответствуют введенным пользователем значениям.

Откройте основной класс приложения DemoApplication и измените его так, чтобы он выглядел следующим образом:

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();
  }
}

Обратите внимание, что мы аннотировали класс с помощью @ShellComponent . Это сообщает Spring, что мы хотим использовать этот класс как источник команд CLI. Методы, аннотированные @ShellMethod , будут представлены в нашем приложении как команды CLI.

Здесь мы используем методы, объявленные в интерфейсе BookRepository: findByAuthor , findByYearGreaterThan , findByAuthorAndYear . Также мы используем три встроенных метода: save , findAll и deleteAll .

Давайте посмотрим на saveBook Метод. Мы создаём объект Book , используя пользовательские значения для названия, автора и года. Как видите, мы не предоставляем значение id , поэтому оно будет автоматически присвоено полю id при сохранении. Метод save принимает объект типа Book и сохраняет его в Cloud Datastore. Он возвращает объект Book со всеми заполненными полями, включая поле id . В результате мы возвращаем строковое представление этого объекта.

Остальные методы работают аналогично: они принимают переданные параметры соответствующим методам репозитория и возвращают строковые результаты.

Чтобы собрать и запустить приложение, выполните эту команду в Cloud Shell (из корня проекта datastore-example/ , где находится файл pom.xml ):

$ mvn spring-boot:run

После успешного этапа сборки появится логотип Spring и приглашение оболочки:

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


shell:> 

Теперь вы можете поэкспериментировать с командами, которые мы определили ранее. Чтобы просмотреть список команд, используйте команду help:

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>

Попробуйте следующее:

  1. Создайте несколько книг с помощью save-book команда
  2. Выполните поиск с помощью find-all-books команда
  3. Найти книги определенного автора ( find-by-author <author> )
  4. Найти книги, опубликованные после определенного года ( find-by-year-after <year> )
  5. Найти книги по определенному автору и году ( find-by-author-year <author> <year> )

Чтобы увидеть, как сущности хранятся в Cloud Datastore, перейдите в GCP Console и выберите Меню -> Хранилище данных (в разделе Хранилище) -> Сущности (при необходимости выберите пространство имен «[default]» и вид «books»).

Чтобы очистить данные, удалите все книги с помощью команды remove-all-books из оболочки приложения.

shell:> remove-all-books

Для выхода из приложения используйте команду quit, затем Ctrl+C.

В этой лабораторной работе вы создали интерактивное CLI-приложение, которое может хранить и извлекать объекты из облачного хранилища данных!

Узнать больше

Лицензия

Данная работа распространяется по лицензии Creative Commons Attribution 2.0 Generic License.