אתחול אפליקציית Spring עם Cloud Datastore

1. סקירה כללית

Google Cloud Datastore הוא מסד נתונים מסוג NoSQL לאחסון מסמכים שמיועד להתאמה לעומס (automatic scaling), לביצועים גבוהים ולפיתוח אפליקציות בקלות.

מה תלמדו

  • איך להשתמש ב-Cloud Datastore כדי לשמור ולאחזר אובייקטי Java באתחול ב-Spring

מה נדרש

  • פרויקט ב-Google Cloud Platform
  • דפדפן, כמו Chrome או Firefox

איך תשתמשו במדריך הזה?

לקריאה בלבד לקרוא אותו ולבצע את התרגילים

איזה דירוג מגיע לדעתך לחוויית השימוש בשירותי Google Cloud Platform?

מתחילים בינונית בקיאים

2. הגדרה ודרישות

הגדרת סביבה בקצב עצמאי

  1. נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או עושים שימוש חוזר בפרויקט קיים. אם אין לכם עדיין חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Project name הוא השם המוצג של המשתתפים בפרויקט. זו מחרוזת תווים שלא משמשת את Google APIs. תמיד אפשר לעדכן.
  • Project ID הוא ייחודי בכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו (אי אפשר לשנות אותו אחרי שמגדירים אותו). מסוף Cloud יוצר מחרוזת ייחודית באופן אוטומטי; בדרך כלל לא מעניין אותך מה זה. ברוב ה-codelabs תצטרכו להפנות למזהה הפרויקט שלכם (בדרך כלל מזוהה כ-PROJECT_ID). אם המזהה שנוצר לא מוצא חן בעיניכם, אתם יכולים ליצור מזהה אקראי אחר. לחלופין, אפשר לנסות שם משלך ולראות אם הוא זמין. לא ניתן לשנות אותו אחרי השלב הזה, והוא נשאר למשך הפרויקט.
  • לידיעתך, יש ערך שלישי, Project Number, שבו משתמשים בחלק מממשקי ה-API. מידע נוסף על כל שלושת הערכים האלה זמין במסמכי התיעוד.
  1. בשלב הבא צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים או בממשקי API של Cloud. מעבר ב-Codelab הזה לא יעלה הרבה כסף, אם בכלל. כדי להשבית משאבים ולא לצבור חיובים מעבר למדריך הזה, אתם יכולים למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים להשתתף בתוכנית תקופת ניסיון בחינם בשווי 1,200 ש"ח.

הפעלת Cloud Shell

  1. במסוף Cloud, לוחצים על Activate Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים שמתאר מהו. אם הוצג לכם מסך ביניים, לוחצים על המשך.

9c92662c6a846a5c.png

ההקצאה וההתחברות ל-Cloud Shell נמשכת כמה דקות.

9f0e51b578fecce5.png

במכונה הווירטואלית הזו נמצאים כל כלי הפיתוח הדרושים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר משמעותית את ביצועי הרשת והאימות. אם לא את כולן, ניתן לבצע חלק גדול מהעבודה ב-Codelab הזה באמצעות דפדפן.

אחרי ההתחברות ל-Cloud Shell, אתם אמורים לראות שהפרויקט מאומת ושהפרויקט מוגדר לפי מזהה הפרויקט שלכם.

  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 (בקטע Storage) או לוחצים כאן.

אם אף פעם לא השתמשתם ב-Datastore בפרויקט הנוכחי, יופיע המסך Select a Cloud Firestore mode. בוחרים באפשרות Datastore mode (מצב Datastore).

f938295c7ff297f4.png

לאחר מכן, יופיע המסך בחירת מיקום לאחסון הנתונים. בוחרים באפשרות us-east1 או בכל מיקום אזורי אחר ולוחצים על "Create Database" (יצירת מסד נתונים):

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 חדש, וגם pom.xml של Maven, wrapper של Maven ונקודת כניסה לאפליקציה.

האפליקציה שלנו תספק CLI כדי שמשתמשים יוכלו להזין פקודות ולראות תוצאות. אנחנו ניצור מחלקה שתייצג ספר ולאחר מכן נשמור אותה ב-Cloud Datastore באמצעות Datastore Repository.

אנחנו צריכים גם להוסיף עוד תלות הכרחית אחת ל-pom.xml.

כדי לפתוח את Web Code Editor, לוחצים על Open Editor בתפריט של 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. קוד זה מציין שאנחנו רוצים שהשדה הזה ישמש כחלק מהמזהה של מפתח ה-Datastore. לכל ישות של Datastore נדרש מזהה. הסוגים הנתמכים הם 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. כפי שאפשר לנחש, ההטמעה של השיטה הזו תפעיל שאילתה שתשתמש בערך שסופק על ידי המשתמש במסנן התנאי 'שוויון לשדה המחבר'.

השיטה 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 כששומרים אותו. ה-method save מקבלת אובייקט מסוג Book ושומרת אותו ב-Cloud Datastore. היא מחזירה אובייקט Book עם כל השדות שאוכלסו, כולל השדה id. בסוף אנחנו מחזירים ייצוג במחרוזת של האובייקט הזה.

שאר השיטות פועלות באופן דומה: הן מקבלות פרמטרים שמועברים לשיטות המתאימות של המאגר ומחזירות תוצאות בפורמט מחרוזת.

8. הפעלת האפליקציה

כדי לבנות את האפליקציה ולהפעיל אותה, קודם צריך לוודא ש-JAVA_HOME מוגדרת לגרסה הנכונה:

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

מריצים את הפקודה הבאה ב-Cloud Shell (מהרמה הבסיסית (root) של הפרויקט datastore-example/ שבו נמצא pom.xml):

$ ./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 Console. צריך להזין 'ספרים' בשדה הסוג, במידת הצורך.

5fab21a6c89f45a.png

10. הסרת המשאבים

כדי להסיר נתונים, מסירים את כל הספרים באמצעות הפקודה remove-all-books הנכונה ממעטפת האפליקציה.

shell:> remove-all-books

כדי לצאת מהאפליקציה משתמשים בפקודת יציאה ואז ב-Ctrl+C.

11. מעולה!

ב-Codelab הזה יצרתם אפליקציית CLI אינטראקטיבית שיכולה לאחסן ולאחזר אובייקטים מ-Cloud Datastore!

מידע נוסף

רישיון

היצירה הזו בשימוש ברישיון Creative Commons Attribution 2.0 גנרי.