Google Cloud Datastore הוא מסד נתונים מסוג NoSQL לאחסון מסמכים שמיועד להתאמה לעומס (automatic scaling), לביצועים גבוהים ולפיתוח אפליקציות בקלות.
מה תלמדו
- איך משתמשים ב-Cloud Datastore כדי לשמור ולאחזר אובייקטים של Java ב-Spring Boot
מה נדרש
איך תשתמשו במדריך הזה?
איזה דירוג מגיע לדעתך לחוויית השימוש שלך בשירותים של Google Cloud Platform?
הגדרת סביבה בקצב אישי
אם עדיין אין לכם חשבון Google (Gmail או Google Apps), אתם צריכים ליצור חשבון. נכנסים ל-Google Cloud Platform Console (console.cloud.google.com) ויוצרים פרויקט חדש:
חשוב לזכור את מזהה הפרויקט, שהוא שם ייחודי בכל הפרויקטים ב-Google Cloud (השם שמופיע למעלה כבר תפוס ולא יתאים לכם, מצטערים!). בהמשך ה-codelab הזה, נתייחס אליו כאל PROJECT_ID
.
בשלב הבא, תצטרכו להפעיל את החיוב ב-Cloud Console כדי להשתמש במשאבים של Google Cloud.
העלות של התרגיל הזה לא אמורה להיות גבוהה, אבל היא יכולה להיות גבוהה יותר אם תחליטו להשתמש ביותר משאבים או אם תשאירו אותם פועלים (ראו את הקטע 'ניקוי' בסוף המסמך הזה).
משתמשים חדשים ב-Google Cloud Platform זכאים לתקופת ניסיון בחינם בשווי 300$.
הפעלת Google Cloud Shell
ב-GCP Console, לוחצים על סמל Cloud Shell בסרגל הכלים שבפינה השמאלית העליונה:
לאחר מכן לוחצים על 'הפעלת Cloud Shell':
יחלפו כמה רגעים עד שההקצאה והחיבור לסביבת העבודה יושלמו:
המכונה הווירטואלית הזו כוללת את כל הכלים הדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. את רוב העבודה במעבדה הזו, אם לא את כולה, אפשר לבצע באמצעות דפדפן או Google Chromebook.
אחרי שמתחברים ל-Cloud Shell, אמור להופיע אימות שכבר בוצע ושהפרויקט כבר הוגדר לפי PROJECT_ID.
מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהאימות בוצע:
gcloud auth list
פלט הפקודה
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
פלט הפקודה
[core] project = <PROJECT_ID>
אם הוא לא מוגדר, אפשר להגדיר אותו באמצעות הפקודה הבאה:
gcloud config set project <PROJECT_ID>
פלט הפקודה
Updated property [core/project].
ב-GCP Console, עוברים אל Menu -> Datastore (in the Storage section).
אם אף פעם לא השתמשתם ב-Datastore בפרויקט הנוכחי, יופיע המסך Select a Cloud Firestore mode (בחירת מצב Cloud Firestore). בוחרים באפשרות "Datastore mode" (מצב Datastore).
אחרי כן, יוצג המסך Choose where to store your data (בחירת המיקום לאחסון הנתונים). בוחרים באפשרות us-east1 או בכל מיקום אזורי אחר ולוחצים על 'יצירת מסד נתונים':
בסביבת Cloud Shell, משתמשים בפקודה הבאה כדי לאתחל ולבצע bootstrap לאפליקציית Spring Boot חדשה:
$ curl https://start.spring.io/starter.tgz \ -d packaging=war \ -d dependencies=cloud-gcp \ -d baseDir=datastore-example \ -d bootVersion=2.1.1.RELEASE | tar -xzvf -
הפעולה הזו תיצור ספרייה חדשה בשם datastore-example/
עם פרויקט Maven חדש, בנוסף ל-pom.xml
של Maven, ל-Maven Wrapper ולנקודת כניסה לאפליקציה.
האפליקציה שלנו תספק למשתמשים CLI שבו הם יוכלו להזין פקודות ולראות את התוצאות. ניצור מחלקה שתייצג ספר, ואז נשמור אותה ב-Cloud Datastore באמצעות Datastore Repository.
צריך גם להוסיף עוד תלות נדרשת ל-pom.xml
.
פותחים את עורך הקוד האינטרנטי על ידי לחיצה על Launch code editor (הפעלת עורך הקוד) בתפריט Cloud Shell.
אחרי שהעורך נטען, משנים את הקובץ pom.xml
כדי להוסיף את התלות של Spring Data Cloud Datastore Spring Boot starter:
pom.xml
<project>
...
<dependencies>
...
<!-- Add GCP Datastore Starter -->
<dependency>
<groupId>org.springframework.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>2.0.0.RELEASE</version>
</dependency>
</dependencies>
</project>
בעורך, יוצרים את המחלקה Book
עם התוכן הבא:
datastore-example/src/main/java/com/example/demo/Book.java
package com.example.demo;
import org.springframework.cloud.gcp.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
כדי שהייצוג של האובייקטים כמחרוזת יהיה קריא יותר. זה יהיה שימושי כשנדפיס אותם.
אל תשכחו לשמור את הקובץ!
יוצרים את הכיתה BookRepository
עם התוכן הבא:
datastore-example/src/main/java/com/example/demo/BookRepository.java
package com.example.demo;
import java.util.List;
import org.springframework.cloud.gcp.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
מריצה שאילתה שמסננת את השדה year (שנה) לפי ערך שגדול מהערך שהמשתמש סיפק.
findByAuthorAndYear
מבצע שאילתה שמחפשת ישויות שבהן השדות של המחבר והשנה תואמים לערכים שהמשתמש סיפק.
פותחים את המחלקה הראשית של האפליקציה 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 באפליקציה שלנו.
כאן אנחנו משתמשים ב-methods שהצהרנו עליהן בממשק BookRepository: findByAuthor
, findByYearGreaterThan
, findByAuthorAndYear
. בנוסף, אנחנו משתמשים בשלוש שיטות מובנות: save
, findAll
ו-deleteAll
.
נבחן את השיטה saveBook
. אנחנו יוצרים אובייקט Book
באמצעות ערכים שסופקו על ידי המשתמש לגבי שם הפריט, המחבר והשנה. כפי שאפשר לראות, לא ציינו ערך ל-id
, ולכן הוא יוקצה ויוגדר אוטומטית לשדה המזהה כשנשמור את השינויים. השיטה save
מקבלת אובייקט מסוג Book
ושומרת אותו ב-Cloud Datastore. הפונקציה מחזירה אובייקט Book
עם כל השדות מאוכלסים, כולל השדה id
. בסופו של דבר, הפונקציה מחזירה ייצוג מחרוזתי של האובייקט הזה.
שאר השיטות פועלות באופן דומה: הן מקבלות פרמטרים שמועברים לשיטות המאגר המתאימות ומחזירות תוצאות שהומרו למחרוזת.
כדי לבנות ולהפעיל את האפליקציה, מריצים את הפקודה הזו ב-Cloud Shell (משורש הפרויקט datastore-example/
שבו נמצא הקובץ pom.xml
) :
$ mvn spring-boot:run
אחרי שלב בנייה מוצלח, הלוגו של Spring יופיע וההנחיה של המעטפת תופיע:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.1.RELEASE) 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>
)
כדי לראות איך הישויות מאוחסנות ב-Cloud Datastore, עוברים אל GCP Console ולוחצים על Menu -> Datastore (in the Storage section) -> Entities (בוחרים את מרחב השמות [default] ואת סוג הספרים, אם צריך).
כדי לנקות את הנתונים, מסירים את כל הספרים באמצעות הפקודה remove-all-books
משורת הפקודות של האפליקציה.
shell:> remove-all-books
כדי לצאת מהאפליקציה, משתמשים בפקודה quit ואז ב-Ctrl+C.
ב-codelab הזה יצרתם אפליקציית CLI אינטראקטיבית שיכולה לאחסן ולאחזר אובייקטים מ-Cloud Datastore.
מידע נוסף
- Cloud Datastore: https://cloud.google.com/datastore/
- Spring Shell: https://projects.spring.io/spring-shell/
- פרויקט Spring ב-GCP: http://cloud.spring.io/spring-cloud-gcp/
- מאגר GitHub של Spring ב-GCP: https://github.com/spring-cloud/spring-cloud-gcp
- Java ב-Google Cloud Platform: https://cloud.google.com/java/
רישיון
העבודה הזו בשימוש במסגרת רישיון Creative Commons כללי מגרסה 2.0 המותנה בייחוס.