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

1. Обзор

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

Что вы узнаете

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

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

  • Проект Google Cloud Platform
  • Браузер, например Chrome или Firefox.

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

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

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

Новичок Средний Профессионал

2. Настройка и требования

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

  1. Войдите в консоль Google Cloud и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Название проекта — это отображаемое имя участников данного проекта. Это строка символов, не используемая API Google. Вы всегда можете его изменить.
  • Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (его нельзя изменить после установки). Консоль Cloud автоматически генерирует уникальную строку; обычно вам неважно, какая она. В большинстве практических заданий вам потребуется указать идентификатор вашего проекта (обычно обозначается как PROJECT_ID ). Если сгенерированный идентификатор вас не устраивает, вы можете сгенерировать другой случайный идентификатор. В качестве альтернативы вы можете попробовать свой собственный и посмотреть, доступен ли он. После этого шага его нельзя изменить, и он сохраняется на протяжении всего проекта.
  • К вашему сведению, существует третье значение — номер проекта , которое используется некоторыми API. Подробнее обо всех трех значениях можно узнать в документации .
  1. Далее вам потребуется включить оплату в консоли Cloud для использования ресурсов/API Cloud. Выполнение этого практического задания не потребует больших затрат, если вообще потребует. Чтобы отключить ресурсы и избежать дополнительных расходов после завершения этого урока, вы можете удалить созданные ресурсы или удалить проект. Новые пользователи Google Cloud имеют право на бесплатную пробную версию стоимостью 300 долларов США .

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

  1. В консоли Cloud нажмите «Активировать Cloud Shell» . 853e55310c205094.png .

55efc1aaa7a4d3ad.png

Если вы запускаете Cloud Shell впервые, вам будет показан промежуточный экран с описанием его возможностей. Если вам был показан промежуточный экран, нажмите «Продолжить» .

9c92662c6a846a5c.png

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

9f0e51b578fecce5.png

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

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

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

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

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project

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

[core]
project = <PROJECT_ID>

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

gcloud config set project <PROJECT_ID>

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

Updated property [core/project].

3. Инициализация облачного хранилища данных.

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

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

f938295c7ff297f4.png

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

916ac84fec10fae7.png

4. Инициализация нового Java-приложения Spring Boot.

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

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

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

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

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

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

6d823258c76a7452.png

После загрузки редактора измените файл pom.xml , добавив зависимости Google Cloud Datastore Starter и Spring Shell Starter:

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. Создайте класс Book.

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

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

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

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

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

6. Создайте интерфейс BookRepository.

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

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

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

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

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

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

7. Создайте интерактивное приложение командной строки.

Откройте основной класс приложения 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 . В конце мы возвращаем строковое представление этого объекта.

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

8. Запустите приложение.

Для сборки и запуска приложения сначала убедитесь, что переменная JAVA_HOME установлена ​​на правильную версию:

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

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

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

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

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



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>

9. Просмотрите содержимое хранилища данных с помощью веб-интерфейса.

Чтобы узнать, как хранятся сущности в Cloud Datastore, перейдите в консоль GCP . При необходимости введите «books» в поле «тип».

5fab21a6c89f45a.png

10. Уборка

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

shell:> remove-all-books

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

11. Поздравляем!

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

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

Лицензия

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