Google Cloud Datastore — это база данных документов NoSQL, созданная для автоматического масштабирования, высокой производительности и простоты разработки приложений.
Чему вы научитесь
- Как использовать Cloud Datastore для сохранения и извлечения объектов Java в Spring Boot
Что вам понадобится
Как вы будете использовать это руководство?
Как бы вы оценили свой опыт использования сервисов Google Cloud Platform?
Настройка среды для самостоятельного обучения
Если у вас ещё нет учётной записи Google (Gmail или Google Apps), необходимо её создать . Войдите в консоль Google Cloud Platform ( console.cloud.google.com ) и создайте новый проект:
Запомните идентификатор проекта — уникальное имя для всех проектов 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>
Попробуйте следующее:
- Создайте несколько книг с помощью
save-book
команда - Выполните поиск с помощью
find-all-books
команда - Найти книги определенного автора (
find-by-author <author>
) - Найти книги, опубликованные после определенного года (
find-by-year-after <year>
) - Найти книги по определенному автору и году (
find-by-author-year <author> <year>
)
Чтобы увидеть, как сущности хранятся в Cloud Datastore, перейдите в GCP Console и выберите Меню -> Хранилище данных (в разделе Хранилище) -> Сущности (при необходимости выберите пространство имен «[default]» и вид «books»).
Чтобы очистить данные, удалите все книги с помощью команды remove-all-books
из оболочки приложения.
shell:> remove-all-books
Для выхода из приложения используйте команду quit, затем Ctrl+C.
В этой лабораторной работе вы создали интерактивное CLI-приложение, которое может хранить и извлекать объекты из облачного хранилища данных!
Узнать больше
- Облачное хранилище данных: https://cloud.google.com/datastore/
- Spring Shell: https://projects.spring.io/spring-shell/
- Проект Spring на GCP: http://cloud.spring.io/spring-cloud-gcp/
- Репозиторий Spring на GCP GitHub: https://github.com/spring-cloud/spring-cloud-gcp
- Java на облачной платформе Google: https://cloud.google.com/java/
Лицензия
Данная работа распространяется по лицензии Creative Commons Attribution 2.0 Generic License.