1. Обзор
Google Cloud Datastore — это документоориентированная база данных NoSQL, созданная для автоматического масштабирования, высокой производительности и упрощения разработки приложений.
Что вы узнаете
- Как использовать Cloud Datastore для сохранения и извлечения Java-объектов в Spring Boot
Что вам понадобится
Как вы будете использовать этот учебный материал?
Как бы вы оценили свой опыт использования сервисов Google Cloud Platform?
2. Настройка и требования
Настройка среды для самостоятельного обучения
- Войдите в консоль Google Cloud и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .



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

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

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

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Большая часть, если не вся, ваша работа в этом практическом задании может быть выполнена с помощью браузера.
После подключения к Cloud Shell вы увидите, что прошли аутентификацию и что проект настроен на ваш идентификатор проекта.
- Выполните следующую команду в 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`
- Выполните следующую команду в 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» .

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

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.

После загрузки редактора измените файл 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>
Попробуйте следующее:
- Создайте несколько книг, используя команду
save-book - Выполните поиск с помощью команды
find-all-books - Найти книги по конкретному автору:
find-by-author <author> - Найти книги, изданные после определенного года:
find-by-year-after <year> - Поиск книг по конкретному автору и году:
find-by-author-year <author> <year>
9. Просмотрите содержимое хранилища данных с помощью веб-интерфейса.
Чтобы узнать, как хранятся сущности в Cloud Datastore, перейдите в консоль GCP . При необходимости введите «books» в поле «тип».

10. Уборка
Для очистки удалите все книги, используя команду remove-all-books из командной оболочки приложения.
shell:> remove-all-books
Для выхода из приложения используйте команду «Выход», затем Ctrl+C .
11. Поздравляем!
В этом практическом задании вы создали интерактивное CLI-приложение, которое может сохранять и извлекать объекты из Cloud Datastore!
Узнать больше
- Облачное хранилище данных: https://cloud.google.com/datastore/
- Spring Shell: https://projects.spring.io/spring-shell/
- Проект Spring на GCP: https://spring.io/projects/spring-cloud-gcp
- Репозиторий Spring на GCP на GitHub: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java на платформе Google Cloud: https://cloud.google.com/java/
Лицензия
Данная работа распространяется под лицензией Creative Commons Attribution 2.0 Generic.