1. 總覽
Google Cloud Datastore 是專為自動調整資源配置、提供高效能及便利開發應用程式所打造的 NoSQL 文件資料庫。
課程內容
- 如何在 Spring Boot 中使用 Cloud Datastore 儲存及擷取 Java 物件
軟硬體需求
您會如何使用這個教學課程?
根據您使用 Google Cloud Platform 服務的經驗,您會給予什麼評價?
2. 設定和需求
自修環境設定
- 登入 Google Cloud 控制台,建立新專案或重複使用現有專案。如果您還沒有 Gmail 或 Google Workspace 帳戶,請先建立帳戶。
- 「專案名稱」是這項專案參與者的顯示名稱。這是 Google API 未使用的字元字串。你隨時可以更新。
- 所有 Google Cloud 專案的專案 ID 均不得重複,而且設定後即無法變更。Cloud 控制台會自動產生一個不重複的字串。但通常是在乎它何在在大部分的程式碼研究室中,您必須參照專案 ID (通常為
PROJECT_ID
)。如果您對產生的 ID 不滿意,可以隨機產生一個 ID。或者,您也可以自行嘗試,看看是否支援。在這個步驟後,這個名稱即無法變更,而且在專案期間內仍會保持有效。 - 資訊中的第三個值是專案編號,部分 API 會使用這個編號。如要進一步瞭解這三個值,請參閱說明文件。
- 接下來,您需要在 Cloud 控制台中啟用計費功能,才能使用 Cloud 資源/API。執行本程式碼研究室不會產生任何費用 (如果有的話)。如要關閉資源,以免產生本教學課程結束後產生的費用,您可以刪除自己建立的資源或刪除專案。新使用者符合 $300 美元免費試用計畫的資格。
啟用 Cloud Shell
- 在 Cloud 控制台中,按一下「啟用 Cloud Shell」圖示 。
如果您是第一次啟動 Cloud Shell,系統會顯示中繼畫面,說明這項服務的內容。如果系統顯示中繼畫面,請按一下「繼續」。
佈建並連線至 Cloud Shell 只需幾分鐘的時間。
這個虛擬機器已載入所有必要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。在本程式碼研究室中,您的大部分作業都可透過瀏覽器完成。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。
- 在 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. 初始化 Cloud Datastore
在 GCP 控制台中,前往「選單」->Datastore (位於「儲存空間」專區) 或按這裡。
如果您從未在目前的專案中使用 Datastore,就會看到「選取 Cloud Firestore 模式」畫面。選取「Datastore mode」選項。
之後,系統會顯示「Choose where to store your data」(選擇資料的儲存位置) 畫面。選取 us-east1 或其他區域位置,然後按一下「建立資料庫」:
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 選單中的「開啟編輯器」,開啟網頁程式碼編輯器。
載入編輯器後,請修改 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。支援的類型為 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
類型。我們在存放區中宣告三種查詢方法,哪些實作會在背景自動產生。
第 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
介面內宣告的方法: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 中執行以下指令 (從 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>
請嘗試按照下列步驟操作:
- 使用
save-book
指令建立幾本書籍 - 使用
find-all-books
指令執行搜尋 - 尋找特定作者的書籍:
find-by-author <author>
- 尋找特定日期後出版的書籍:
find-by-year-after <year>
- 依特定作者和年份尋找書籍:
find-by-author-year <author> <year>
9. 使用網頁介面查看 Datastore 中儲存的內容
如要瞭解實體在 Cloud Datastore 中的儲存方式,請前往 GCP 主控台。輸入「books」的值。
10. 清除所用資源
如要清理書籍,請在應用程式殼層中使用適當命名的 remove-all-books
指令移除所有書籍。
shell:> remove-all-books
如要結束應用程式,請使用結束指令,然後設為 Ctrl+C
。
11. 恭喜!
在本程式碼研究室中,您已建立互動式 CLI 應用程式,可儲存及擷取 Cloud Datastore 中的物件!
瞭解詳情
- Cloud Datastore:https://cloud.google.com/datastore/
- Spring Shell:https://projects.spring.io/spring-shell/
- GCP 專案的 Spring:https://spring.io/projects/spring-cloud-gcp
- GCP GitHub 存放區的 Spring:https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- 在 Google Cloud Platform 上使用 Java:https://cloud.google.com/java/
授權
這項內容採用的是創用 CC 姓名標示 2.0 通用授權。