Ứng dụng Spring Boot với Cloud Datastore

1. Tổng quan

Google Cloud Datastore là một cơ sở dữ liệu tài liệu NoSQL, được xây dựng để tự động mở rộng quy mô, đạt hiệu suất cao và dễ dàng phát triển ứng dụng.

Kiến thức bạn sẽ học được

  • Cách sử dụng Cloud Datastore để lưu và truy xuất đối tượng java trong Spring Boot

Bạn cần có

  • Một dự án trên Google Cloud Platform
  • Một trình duyệt, chẳng hạn như Chrome hoặc Firefox

Bạn sẽ sử dụng hướng dẫn này như thế nào?

Chỉ có thể đọc Đọc và hoàn thành bài tập

Bạn đánh giá trải nghiệm sử dụng các dịch vụ của Google Cloud Platform như thế nào?

Người mới tập Trung cấp Thành thạo

2. Thiết lập và yêu cầu

Thiết lập môi trường theo tiến độ riêng

  1. Đăng nhập vào Google Cloud Console rồi tạo dự án mới hoặc sử dụng lại dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Tên dự án là tên hiển thị của những người tham gia dự án này. Đây là một chuỗi ký tự không được API của Google sử dụng. Bạn luôn có thể cập nhật ứng dụng.
  • Mã dự án là duy nhất trong tất cả các dự án Google Cloud và không thể thay đổi (không thể thay đổi sau khi đã đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường bạn không quan tâm đến sản phẩm đó là gì. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham khảo Mã dự án (thường được xác định là PROJECT_ID). Nếu không thích mã đã tạo, bạn có thể tạo một mã nhận dạng ngẫu nhiên khác. Ngoài ra, bạn có thể thử cách riêng của mình để xem có thể sử dụng hay không. Bạn không thể thay đổi mã này sau bước này và mã vẫn giữ nguyên trong thời gian của dự án.
  • Đối với thông tin của bạn, có giá trị thứ ba, Project Number (Số dự án), mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu này.
  1. Tiếp theo, bạn sẽ phải bật tính năng thanh toán trong Cloud Console để sử dụng API/tài nguyên trên đám mây. Việc chạy qua lớp học lập trình này sẽ không tốn nhiều chi phí. Để tắt các tài nguyên nhằm tránh phát sinh việc thanh toán ngoài hướng dẫn này, bạn có thể xoá các tài nguyên bạn đã tạo hoặc xoá dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.

Kích hoạt Cloud Shell

  1. Trong Cloud Console, hãy nhấp vào Kích hoạt Cloud Shell 853e55310c205094.pngs.

55efc1aaa7a4d3ad.pngS

Nếu đây là lần đầu tiên khởi động Cloud Shell, bạn sẽ thấy một màn hình trung gian mô tả về Cloud Shell. Nếu bạn nhìn thấy màn hình trung gian, hãy nhấp vào Tiếp tục.

9c92662c6a846a5c.pngS

Quá trình cấp phép và kết nối với Cloud Shell chỉ mất vài phút.

9f0e51b578fecce5.pngs

Máy ảo này được tải tất cả các công cụ phát triển cần thiết. Dịch vụ này cung cấp thư mục gốc có dung lượng ổn định 5 GB và chạy trên Google Cloud, giúp nâng cao đáng kể hiệu suất và khả năng xác thực của mạng. Nhiều (nếu không nói là) tất cả công việc của bạn trong lớp học lập trình này đều có thể thực hiện bằng trình duyệt.

Sau khi kết nối với Cloud Shell, bạn sẽ thấy mình đã được xác thực và dự án được đặt thành mã dự án.

  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng bạn đã được xác thực:
gcloud auth list

Kết quả lệnh

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng lệnh gcloud biết về dự án của bạn:
gcloud config list project

Kết quả lệnh

[core]
project = <PROJECT_ID>

Nếu chưa, bạn có thể thiết lập chế độ này bằng lệnh sau:

gcloud config set project <PROJECT_ID>

Kết quả lệnh

Updated property [core/project].

3. Khởi chạy Cloud Datastore

Trong Bảng điều khiển GCP, hãy chuyển đến Trình đơn -> Datastore (trong phần Bộ nhớ) hoặc nhấp vào đây.

Nếu chưa từng sử dụng Datastore trong dự án hiện tại, bạn sẽ thấy màn hình "Chọn chế độ Cloud Firestore". Chọn lựa chọn "Chế độ kho dữ liệu".

f938295c7ff297f4.png

Sau đó, bạn sẽ thấy màn hình "Chọn nơi lưu trữ dữ liệu của bạn". Chọn us-east1 hoặc bất kỳ vị trí khu vực nào khác và nhấp vào "Tạo cơ sở dữ liệu":

916ac84fec10fae7.pngs

4. Tự thân khởi động một ứng dụng Java khởi động mùa xuân mới

Từ môi trường CloudShell, hãy sử dụng lệnh sau để khởi chạy và khởi động một ứng dụng Spring Boot mới:

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

Thao tác này sẽ tạo một thư mục datastore-example/ mới có một dự án Maven mới, cùng với pom.xml của Maven, một trình bao bọc Maven và một điểm nhập ứng dụng.

Ứng dụng của chúng tôi sẽ cung cấp CLI để người dùng nhập lệnh và xem kết quả. Chúng ta sẽ tạo một lớp để đại diện cho một cuốn sách, sau đó sẽ lưu cuốn sách đó vào Cloud Datastore bằng cách sử dụng Kho lưu trữ dữ liệu.

Chúng ta cũng cần thêm một phần phụ thuộc cần thiết nữa vào pom.xml.

Mở Trình soạn thảo mã web bằng cách nhấp vào Open Editor (Mở trình chỉnh sửa) trên trình đơn Cloud Shell.

6d823258c76a7452.pngS

Sau khi trình chỉnh sửa tải, hãy sửa đổi tệp pom.xml để thêm các phần phụ thuộc của Google Cloud Datastore Starter và 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. Tạo lớp Sách

Sử dụng trình chỉnh sửa để tạo lớp Book với nội dung sau:

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

Như bạn có thể thấy, đây là một POJO đơn giản. Lớp này được chú thích bằng @Entity để cho biết rằng lớp này có thể được lưu trữ trong Datastore và cung cấp tên loại (hãy coi một loại là một bảng trong cơ sở dữ liệu SQL, xem tài liệu để biết thêm chi tiết). Tên loại là không bắt buộc. Nếu bạn bỏ qua tên này, tên loại sẽ được tạo dựa trên tên lớp.

Xin lưu ý rằng chúng ta đã chú thích thuộc tính id bằng @Id. Điều đó cho biết rằng chúng ta muốn sử dụng trường này làm phần nhận dạng của Khoá kho dữ liệu. Mỗi thực thể Datastore đều cần có một giá trị nhận dạng. Các kiểu được hỗ trợ là StringLong.

Chúng ta ghi đè phương thức toString để giúp cách trình bày chuỗi của các đối tượng dễ đọc hơn; điều này sẽ có ích khi chúng ta in ra.

6. Tạo giao diện BookRepository

Tạo lớp BookRepository với nội dung sau:

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

Giao diện này mở rộng DatastoreRepository<Book, Long>, trong đó Book là lớp miền và Long là loại Id. Chúng ta khai báo 3 phương thức truy vấn trong kho lưu trữ của mình. Các phương thức triển khai được tạo tự động ở chế độ nền.

Tin nhắn đầu tiên là findByAuthor. Như bạn có thể đoán, việc triển khai phương thức này sẽ thực thi một truy vấn sử dụng giá trị do người dùng cung cấp trong bộ lọc điều kiện để tìm giá trị bằng với trường tác giả.

Phương thức findByYearGreaterThan thực thi truy vấn lọc ra trường năm lớn hơn giá trị do người dùng cung cấp.

findByAuthorAndYear thực thi truy vấn để tìm các thực thể có trường tác giả và năm năm khớp với giá trị do người dùng cung cấp.

7. Tạo ứng dụng CLI có tính tương tác

Mở lớp DemoApplication của ứng dụng chính rồi sửa đổi thành như sau:

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

Hãy lưu ý cách chúng ta chú thích lớp bằng @ShellComponent. Điều đó thông báo cho Spring biết rằng chúng ta muốn sử dụng lớp này làm nguồn cho các lệnh CLI. Các phương thức được chú giải bằng @ShellMethod sẽ hiển thị dưới dạng lệnh CLI trong ứng dụng của chúng ta.

Ở đây, chúng ta sử dụng các phương thức đã khai báo trong giao diện BookRepository: findByAuthor, findByYearGreaterThan, findByAuthorAndYear. Ngoài ra, chúng ta còn sử dụng 3 phương thức tích hợp sẵn: save, findAlldeleteAll.

Hãy xem phương thức saveBook. Chúng ta tạo đối tượng Book bằng các giá trị do người dùng cung cấp cho tiêu đề, tác giả và năm. Như bạn có thể thấy, chúng ta không cung cấp giá trị id nên giá trị này sẽ tự động được phân bổ và chỉ định cho trường id khi lưu. Phương thức save chấp nhận một đối tượng thuộc loại Book và lưu đối tượng đó vào Cloud Datastore. Phương thức này trả về một đối tượng Book có tất cả các trường được điền sẵn, bao gồm cả trường id. Cuối cùng, chúng ta sẽ trả về một chuỗi đại diện của đối tượng này.

Các phương thức còn lại sẽ hoạt động tương tự như vậy: chúng chấp nhận việc truyền tham số vào các phương thức kho lưu trữ thích hợp và trả về kết quả dạng chuỗi.

8. Chạy ứng dụng

Để tạo và khởi động ứng dụng, trước tiên, hãy đảm bảo bạn đã đặt JAVA_HOME theo đúng phiên bản:

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

Thực thi lệnh này trong Cloud Shell (từ thư mục gốc của dự án datastore-example/, nơi đặt pom.xml):

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

Sau khi hoàn tất giai đoạn tạo bản dựng thành công, biểu trưng lò xo sẽ xuất hiện và lời nhắc shell sẽ xuất hiện:

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



shell:>

Bây giờ, bạn có thể thử nghiệm với các lệnh mà chúng ta đã xác định trước đó. Để xem danh sách các lệnh, hãy dùng lệnh trợ giúp:

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>

Hãy thử các cách sau:

  1. Tạo một số cuốn sách bằng lệnh save-book
  2. Dùng lệnh find-all-books để chạy tìm kiếm
  3. Tìm sách theo tác giả cụ thể: find-by-author <author>
  4. Tìm sách được xuất bản sau một năm cụ thể: find-by-year-after <year>
  5. Tìm sách theo tác giả và năm cụ thể: find-by-author-year <author> <year>

9. Xem nội dung được lưu trữ trong Datastore bằng giao diện web

Để xem cách các thực thể được lưu trữ trong Cloud Datastore, hãy chuyển đến Bảng điều khiển GCP. Nhập "sách" trong trường loại, nếu cần.

5fab21a6c89f45a.png.

10. Dọn dẹp

Để dọn dẹp, hãy xoá tất cả sách bằng lệnh remove-all-books được đặt tên phù hợp khỏi giao diện ứng dụng.

shell:> remove-all-books

Để thoát khỏi ứng dụng, hãy dùng lệnh thoát, sau đó dùng Ctrl+C.

11. Xin chúc mừng!

Trong lớp học lập trình này, bạn đã tạo một ứng dụng CLI có thể tương tác để lưu trữ và truy xuất đối tượng từ Cloud Datastore!

Tìm hiểu thêm

Giấy phép

Tác phẩm này được cấp phép theo Giấy phép chung Ghi nhận tác giả Creative Commons 2.0.