使用 Cloud Datastore 的 Spring Boot 應用程式

1. 總覽

Google Cloud Datastore 是專為自動調整資源配置、提供高效能及便利開發應用程式所打造的 NoSQL 文件資料庫。

課程內容

  • 如何在 Spring Boot 中使用 Cloud Datastore 儲存及擷取 Java 物件

軟硬體需求

  • Google Cloud Platform 專案
  • 瀏覽器,例如 ChromeFirefox

您會如何使用這個教學課程?

僅供閱讀 閱讀並完成練習

根據您使用 Google Cloud Platform 服務的經驗,您會給予什麼評價?

新手 中級 還算容易

2. 設定和需求

自修環境設定

  1. 登入 Google Cloud 控制台,建立新專案或重複使用現有專案。如果您還沒有 Gmail 或 Google Workspace 帳戶,請先建立帳戶

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 「專案名稱」是這項專案參與者的顯示名稱。這是 Google API 未使用的字元字串。你隨時可以更新。
  • 所有 Google Cloud 專案的專案 ID 均不得重複,而且設定後即無法變更。Cloud 控制台會自動產生一個不重複的字串。但通常是在乎它何在在大部分的程式碼研究室中,您必須參照專案 ID (通常為 PROJECT_ID)。如果您對產生的 ID 不滿意,可以隨機產生一個 ID。或者,您也可以自行嘗試,看看是否支援。在這個步驟後,這個名稱即無法變更,而且在專案期間內仍會保持有效。
  • 資訊中的第三個值是專案編號,部分 API 會使用這個編號。如要進一步瞭解這三個值,請參閱說明文件
  1. 接下來,您需要在 Cloud 控制台中啟用計費功能,才能使用 Cloud 資源/API。執行本程式碼研究室不會產生任何費用 (如果有的話)。如要關閉資源,以免產生本教學課程結束後產生的費用,您可以刪除自己建立的資源或刪除專案。新使用者符合 $300 美元免費試用計畫的資格。

啟用 Cloud Shell

  1. 在 Cloud 控制台中,按一下「啟用 Cloud Shell」圖示 853e55310c205094.png

55efc1aaa7a4d3ad.png

如果您是第一次啟動 Cloud Shell,系統會顯示中繼畫面,說明這項服務的內容。如果系統顯示中繼畫面,請按一下「繼續」

9c92662c6a846a5c.png

佈建並連線至 Cloud Shell 只需幾分鐘的時間。

9f0e51b578fecce5.png

這個虛擬機器已載入所有必要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。在本程式碼研究室中,您的大部分作業都可透過瀏覽器完成。

連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。

  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. 初始化 Cloud Datastore

GCP 控制台中,前往「選單」->Datastore (位於「儲存空間」專區) 或按這裡

如果您從未在目前的專案中使用 Datastore,就會看到「選取 Cloud Firestore 模式」畫面。選取「Datastore mode」選項。

f938295c7ff297f4.png

之後,系統會顯示「Choose where to store your data」(選擇資料的儲存位置) 畫面。選取 us-east1 或其他區域位置,然後按一下「建立資料庫」:

916ac84fec10fae7.png

4. 啟動新的 Spring Boot Java 應用程式

在 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 專案,以及 Maven 的 pom.xml、Maven 包裝函式和應用程式進入點。

我們的應用程式會提供 CLI,讓使用者輸入指令及查看結果。我們會建立類別來代表書籍,然後使用 Datastore Repository 將書籍儲存至 Cloud 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 類別:

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 註解。這表示我們想要使用這個欄位做為資料儲存庫金鑰的 ID 部分。每個 Datastore 實體都需要一個 ID。支援的類型為 StringLong

我們會覆寫 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 是網域類別,LongId 類型。我們在存放區中宣告三種查詢方法,哪些實作會在背景自動產生。

第 1 個是「findByAuthor」。讓您可以猜測,此方法的實作會執行查詢,而此查詢會在條件篩選器中使用使用者提供的值來比對作者欄位。

findByYearGreaterThan 方法會執行查詢,篩選年份欄位的值大於使用者提供的值。

findByAuthorAndYear 會執行查詢,尋找作者和年份欄位與使用者提供的值相符的實體。

7. 建立互動式 CLI 應用程式

開啟主要應用程式 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 介面內宣告的方法:findByAuthorfindByYearGreaterThanfindByAuthorAndYear。此外,我們也使用三種內建方法:savefindAlldeleteAll

一起來看看 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 中執行以下指令 (從 pom.xml 所在的專案 datastore-example/ 的根目錄):

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

建構階段成功後,畫面中會顯示「春季」標誌,並顯示殼層提示:

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



shell:>

現在,您可以嘗試使用先前定義的指令。如要查看指令清單,請使用說明指令:

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. 使用網頁介面查看 Datastore 中儲存的內容

如要瞭解實體在 Cloud Datastore 中的儲存方式,請前往 GCP 主控台。輸入「books」的值。

5fab21a6c89f45a.png

10. 清除所用資源

如要清理書籍,請在應用程式殼層中使用適當命名的 remove-all-books 指令移除所有書籍。

shell:> remove-all-books

如要結束應用程式,請使用結束指令,然後設為 Ctrl+C

11. 恭喜!

在本程式碼研究室中,您已建立互動式 CLI 應用程式,可儲存及擷取 Cloud Datastore 中的物件!

瞭解詳情

授權

這項內容採用的是創用 CC 姓名標示 2.0 通用授權。