1. סקירה כללית
Google Cloud Datastore הוא מסד נתונים מסוג NoSQL לאחסון מסמכים שמיועד להתאמה לעומס (automatic scaling), לביצועים גבוהים ולפיתוח אפליקציות בקלות.
מה תלמדו
- איך להשתמש ב-Cloud Datastore כדי לשמור ולאחזר אובייקטי Java באתחול ב-Spring
מה נדרש
איך תשתמשו במדריך הזה?
איזה דירוג מגיע לדעתך לחוויית השימוש בשירותי Google Cloud Platform?
2. הגדרה ודרישות
הגדרת סביבה בקצב עצמאי
- נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או עושים שימוש חוזר בפרויקט קיים. אם אין לכם עדיין חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון.
- Project name הוא השם המוצג של המשתתפים בפרויקט. זו מחרוזת תווים שלא משמשת את Google APIs. תמיד אפשר לעדכן.
- Project ID הוא ייחודי בכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו (אי אפשר לשנות אותו אחרי שמגדירים אותו). מסוף Cloud יוצר מחרוזת ייחודית באופן אוטומטי; בדרך כלל לא מעניין אותך מה זה. ברוב ה-codelabs תצטרכו להפנות למזהה הפרויקט שלכם (בדרך כלל מזוהה כ-
PROJECT_ID
). אם המזהה שנוצר לא מוצא חן בעיניכם, אתם יכולים ליצור מזהה אקראי אחר. לחלופין, אפשר לנסות שם משלך ולראות אם הוא זמין. לא ניתן לשנות אותו אחרי השלב הזה, והוא נשאר למשך הפרויקט. - לידיעתך, יש ערך שלישי, Project Number, שבו משתמשים בחלק מממשקי ה-API. מידע נוסף על כל שלושת הערכים האלה זמין במסמכי התיעוד.
- בשלב הבא צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים או בממשקי API של Cloud. מעבר ב-Codelab הזה לא יעלה הרבה כסף, אם בכלל. כדי להשבית משאבים ולא לצבור חיובים מעבר למדריך הזה, אתם יכולים למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים להשתתף בתוכנית תקופת ניסיון בחינם בשווי 1,200 ש"ח.
הפעלת Cloud Shell
- במסוף Cloud, לוחצים על Activate Cloud Shell .
אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים שמתאר מהו. אם הוצג לכם מסך ביניים, לוחצים על המשך.
ההקצאה וההתחברות ל-Cloud Shell נמשכת כמה דקות.
במכונה הווירטואלית הזו נמצאים כל כלי הפיתוח הדרושים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר משמעותית את ביצועי הרשת והאימות. אם לא את כולן, ניתן לבצע חלק גדול מהעבודה ב-Codelab הזה באמצעות דפדפן.
אחרי ההתחברות ל-Cloud Shell, אתם אמורים לראות שהפרויקט מאומת ושהפרויקט מוגדר לפי מזהה הפרויקט שלכם.
- מריצים את הפקודה הבאה ב-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 (בקטע Storage) או לוחצים כאן.
אם אף פעם לא השתמשתם ב-Datastore בפרויקט הנוכחי, יופיע המסך Select a Cloud Firestore mode. בוחרים באפשרות Datastore mode (מצב Datastore).
לאחר מכן, יופיע המסך בחירת מיקום לאחסון הנתונים. בוחרים באפשרות us-east1 או בכל מיקום אזורי אחר ולוחצים על "Create Database" (יצירת מסד נתונים):
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.
אחרי שהעורך נטען, משנים את הקובץ 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>
נסו:
- יצירת כמה ספרים באמצעות הפקודה
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 Console. צריך להזין 'ספרים' בשדה הסוג, במידת הצורך.
10. הסרת המשאבים
כדי להסיר נתונים, מסירים את כל הספרים באמצעות הפקודה remove-all-books
הנכונה ממעטפת האפליקציה.
shell:> remove-all-books
כדי לצאת מהאפליקציה משתמשים בפקודת יציאה ואז ב-Ctrl+C
.
11. מעולה!
ב-Codelab הזה יצרתם אפליקציית CLI אינטראקטיבית שיכולה לאחסן ולאחזר אובייקטים מ-Cloud Datastore!
מידע נוסף
- Cloud Datastore: https://cloud.google.com/datastore/
- Spring Shell: https://projects.spring.io/spring-shell/
- לפרויקט GCP לקראת האביב: https://spring.io/projects/spring-cloud-gcp
- אביב במאגר GitHub של GCP: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java ב-Google Cloud Platform: https://cloud.google.com/java/
רישיון
היצירה הזו בשימוש ברישיון Creative Commons Attribution 2.0 גנרי.