גרף ישות JPA

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

JPA 2.1 הציגה את התכונה Entity Graph כשיטה מתוחכמת יותר להתמודדות עם טעינת ביצועים.

זה מאפשר להגדיר תבנית על ידי קיבוץ שדות ההתמדה הקשורים אותם אנו רוצים לאחזר ומאפשר לנו לבחור את סוג הגרף בזמן הריצה.

במדריך זה נסביר ביתר פירוט כיצד ליצור ולהשתמש בתכונה זו.

2. מה גרף הישות מנסה לפתור

עד JPA 2.0, כדי לטעון שיוך ישויות, בדרך כלל השתמשנו FetchType.עָצֵל ו FetchType.לָהוּט כאסטרטגיות להביא. זה מורה לספק JPA להביא בנוסף את השיוך הקשור או לא. למרבה הצער, תצורת מטא זו היא סטטית ואינו מאפשר לעבור בין שתי האסטרטגיות הללו בזמן הריצה.

המטרה העיקרית של גרף הישות של JPA היא לשפר את ביצועי זמן הריצה בעת טעינת האסוציאציות והשדות הבסיסיים הקשורים ליישות.

בקצרה, ספק ה- JPA טוען את כל הגרפים בשאילתת בחירה אחת ואז נמנע מלהביא שיוך לשאילתות SELECT נוספות. זו נחשבת לגישה טובה לשיפור ביצועי היישומים.

3. הגדרת המודל

לפני שנתחיל לחקור את גרף הישות, עלינו להגדיר את ישויות המודל איתן אנו עובדים. נניח שאנחנו רוצים ליצור אתר בלוגים שבו משתמשים יכולים להגיב ולשתף פוסטים.

אז ראשית יהיה לנו מִשׁתַמֵשׁ יֵשׁוּת:

משתמש בכיתה ציבורית @Entity {@Id @GeneratedValue (אסטרטגיה = GenerationType.IDENTITY) פרטי מזהה ארוך; שם מחרוזת פרטי; דוא"ל מחרוזת פרטי; // ...}

המשתמש יכול לשתף פוסטים שונים, ולכן אנו זקוקים גם ל- הודעה יֵשׁוּת:

@Entity בכיתה ציבורית הודעה {@Id @GeneratedValue (אסטרטגיה = GenerationType.IDENTITY) פרטי מזהה ארוך; נושא מחרוזת פרטי; @OneToMany (mappedBy = "post") הערות רשימה פרטית = ArrayList חדש (); @ManyToOne (fetch = FetchType.LAZY) משתמש משתמש פרטי @JoinColumn; // ...}

המשתמש יכול גם להגיב על ההודעות המשותפות, ולבסוף, נוסיף תגובה יֵשׁוּת:

תגובה בכיתה ציבורית @Entity {@Id @GeneratedValue (אסטרטגיה = GenerationType.IDENTITY) פרטי מזהה ארוך; תשובה מחרוזת פרטית; @ManyToOne (fetch = FetchType.LAZY) @JoinColumn הודעה פרטית; @ManyToOne (fetch = FetchType.LAZY) משתמש משתמש פרטי @JoinColumn; // ...}

כפי שאנו רואים, הודעה לישות יש קשר עם תגובה ו מִשׁתַמֵשׁ ישויות. ה תגובה לישות יש שיוך ל הודעה ו מִשׁתַמֵשׁ ישויות.

המטרה היא לטעון את הגרף הבא בדרכים שונות:

הודעה -> משתמש: משתמש -> הערות: הערות רשימה [0]: תגובה -> משתמש: תגובות משתמשים [1]: תגובה -> משתמש: משתמש

4. טוען ישויות קשורות באמצעות FetchType אסטרטגיות

ה FetchType השיטה מגדירה שתי אסטרטגיות לאיסוף נתונים ממסד הנתונים:

  • FetchType.EAGER: ספק ההתמדה חייב לטעון את השדה או הנכס המסומן. זוהי התנהגות ברירת המחדל של @Basic, @ManyToOne, ו @אחד לאחד הערות שדות.
  • FetchType.LAZY: ספק ההתמדה אמור לטעון נתונים לאחר הגישה הראשונה אליו, אך ניתן לטעון אותו בשקיקה. זוהי התנהגות ברירת המחדל של @OneToMany, @ManyToMany ו @ ElementCollection-הערות שדות.

לדוגמא, כאשר אנו מעמיסים א הודעה הישות, קשורה תגובה ישויות אינן נטענות כברירת מחדל FetchType מאז @אחד לרבים הוא עָצֵל. אנו יכולים לבטל התנהגות זו על ידי שינוי ה- FetchType ל לָהוּט:

@OneToMany (mappedBy = "post", fetch = FetchType.EAGER) הערות פרטיות רשימה = ArrayList חדש ();

לשם השוואה, כאשר אנו מעמיסים א תגובה הישות, שלו הודעה ישות האם נטענת כמצב ברירת המחדל עבור @ManyToOne, שהוא לָהוּט. אנחנו יכולים גם לבחור לא לטעון את הודעה ישות על ידי שינוי ההערה הזו ל- עָצֵל:

@ManyToOne (fetch = FetchType.LAZY) @JoinColumn (name = "post_id") הודעה פרטית של הודעה;

שים לב שכמו עָצֵל אינו דרישה, ספק ההתמדה עדיין יכול לטעון את הודעה ישות בשקיקה אם היא רוצה. אז כדי להשתמש נכון באסטרטגיה זו, עלינו לחזור לתיעוד הרשמי של ספק ההתמדה המתאים.

עכשיו, מכיוון שהשתמשנו בהערות לתיאור אסטרטגיית האחזור שלנו, ההגדרה שלנו היא סטטית ואין דרך לעבור בין ה- עָצֵל ו לָהוּט בזמן ריצה.

כאן נכנס לתמונה גרף הישויות כפי שנראה בסעיף הבא.

5. הגדרת גרף ישויות

כדי להגדיר גרף ישויות, אנו יכולים להשתמש בהערות על הישות או שנוכל להמשיך בתכנות באמצעות ה- JPA API.

5.1. הגדרת גרף ישות עם ביאורים

ה @NamedEntityGraph ביאור מאפשר לציין את התכונות שיש לכלול כאשר אנו רוצים לטעון את הישות ואת האסוציאציות הקשורות.

אז בואו נגדיר תחילה גרף ישויות אשר טוען את ה- הודעה והישויות הקשורות אליו מִשׁתַמֵשׁ ו תגובהs:

@NamedEntityGraph (name = "post-entity-graph", attributeNodes = {@NamedAttributeNode ("subject"), @NamedAttributeNode ("user"), @NamedAttributeNode ("comments"),}) @NativeAttributeNode הודעה {@OneToMany (mappedBy = "post") הערות רשימה פרטית = ArrayList חדש (); // ...}

בדוגמה זו השתמשנו ב- @NamedAttributeNode כדי להגדיר את הישויות הקשורות שיש לטעון כאשר ישות השורש נטענת.

בואו נגדיר כעת גרף ישויות מסובך יותר שבו אנו רוצים גם לטעון את מִשׁתַמֵשׁקשורים ל תגובהס.

לשם כך נשתמש ב- @NamedAttributeNode תכונת משנה. זה מאפשר התייחסות לתצלום בעל שם שהוגדר באמצעות ה- @NamedSubgraph ביאור:

@NamedEntityGraph (name = "post-entity-graph-with-comment-users", attributeNodes = {@NamedAttributeNode ("subject"), @NamedAttributeNode ("user"), @NamedAttributeNode (value = "comments", subgraph = " comments-subgraph "),}, subgraphs = {@NamedSubgraph (name =" comments-subgraph ", attributeNodes = {@NamedAttributeNode (" user ")})}) @Entity class class Post {@OneToMany (mappedBy =" post " ) הערות רשימה פרטית = ArrayList חדש (); // ...}

ההגדרה של @NamedSubgraph ההערה דומה ל- @NamedEntityGraph ומאפשר לציין תכונות של האסוציאציה הקשורה. בכך נוכל לבנות גרף שלם.

בדוגמה לעיל, עם ההגדרה 'פוסט-ישות-גרף-עם-משתמשים-תגובה ' גרף, אנחנו יכולים לטעון את הודעה, הקשור מִשׁתַמֵשׁ, ה הערות וה מִשׁתַמֵשׁקשורים ל הערות.

לסיום, שים לב שנוכל לחילופין להוסיף את ההגדרה של גרף הישות באמצעות ה- orm.xml מתאר פריסה:

  ...     ... 

5.2. הגדרת גרף ישויות באמצעות JPA API

אנו יכולים גם להגדיר את גרף הישויות באמצעות ה- EntityManager API על ידי התקשרות ל- createEntityGraph () שיטה:

EntityGraph entityGraph = entityManager.createEntityGraph (Post.class);

כדי לציין את התכונות של ישות השורש, אנו משתמשים ב- addAttributeNodes () שיטה.

entityGraph.addAttributeNodes ("נושא"); entityGraph.addAttributeNodes ("משתמש");

באופן דומה, כדי לכלול את התכונות מהישות הקשורה, אנו משתמשים ב- addSubgraph () כדי לבנות גרף ישויות מוטבע ואז אנחנו addAttributeNodes () כפי שעשינו לעיל.

entityGraph.addSubgraph ("הערות") .addAttributeNodes ("משתמש");

כעת, כשראינו כיצד ליצור את גרף הישות, נבדוק כיצד להשתמש בו בחלק הבא.

6. שימוש בגרף הישות

6.1. סוגי גרפי ישויות

JPA מגדיר שני מאפיינים או רמזים לפיהם ספק ההתמדה יכול לבחור על מנת לטעון או להביא את גרף הישויות בזמן הריצה:

  • javax.persistence.fetchgraph - רק המאפיינים שצוינו נאספים ממסד הנתונים. כאשר אנו משתמשים ב- Hibernate במדריך זה, אנו יכולים לציין כי בניגוד למפרט JPA, תכונות מוגדרות סטטית כ לָהוּט נטענים גם הם.
  • javax.persistence.loadgraph - בנוסף לתכונות שצוינו, תכונות מוגדרות סטטית כ לָהוּט גם הם אוחזרו.

בשני המקרים, המפתח הראשי והגרסה אם בכלל טעונים תמיד.

6.2. טוען גרף ישויות

אנו יכולים לאחזר את גרף הישויות בדרכים שונות.

נתחיל באמצעות EntityManager.find() שיטה. כפי שכבר הראינו, מצב ברירת המחדל מבוסס על מטא-אסטרטגיות סטטיות FetchType.EAGER ו FetchType.LAZY.

אז בואו נקרא את למצוא() שיטה ולבדוק את היומן:

פוסט פוסט = entityManager.find (Post.class, 1L);

הנה היומן המסופק על ידי יישום שינה:

בחר post0_.id בתור id1_1_0_, post0_. נושא נושא 2_1_0_, post0_.user_id כ user_id3_1_0_ מתוך פוסט post0_ איפה post0_.id =?

כפי שאנו רואים מהיומן, ה- מִשׁתַמֵשׁ ו תגובה ישויות לא נטענות.

אנו יכולים לעקוף התנהגות ברירת מחדל זו על ידי הפעלת עומס יתר למצוא() שיטה המקבלת רמזים כ- מַפָּה. אנחנו יכולים אז ספק את סוג הגרף שאנו רוצים לטעון:

EntityGraph entityGraph = entityManager.getEntityGraph ("גרף פוסט-ישות"); מאפייני מפה = HashMap חדש (); properties.put ("javax.persistence.fetchgraph", entityGraph); פוסט פוסט = entityManager.find (Post.class, id, מאפיינים);

אם נסתכל שוב ביומן, אנו יכולים לראות כי ישויות אלה נטענות כעת ורק בשאילתת בחירה אחת:

בחר post0_.id כ- id1_1_0_, post0_. נושא כ- subject2_1_0_, post0_.user_id כמשתמש_id3_1_0_, comments1_.post_id כמו post_id3_0_1_, comments1_.id כמו id1_0_1_, comments1_.id כמו id1_0_2_, הערות 1_. הודעה_1. .user_id כ- user_id4_0_2_, user2_.id כ- id1_2_3_, user2_.email כמו email2_2_3_, user2_.name כשם3_2_3_ מתוך פוסט post0_ שמאל הצטרף החוצה מזהה איפה post0_.id =?

בואו נראה איך נוכל להשיג את אותו הדבר באמצעות JPQL:

EntityGraph entityGraph = entityManager.getEntityGraph ("פוסט-ישות-גרף-עם-משתמשים-תגובה"); פוסט פוסט = entityManager.createQuery ("בחר p מתוך פוסט p שבו p.id =: id", Post.class). SetParameter ("id", id). SetHint ("javax.persistence.fetchgraph", entityGraph) .getSingleResult ();

ולסיום, בואו נסתכל על א קריטריונים דוגמה ל- API:

EntityGraph entityGraph = entityManager.getEntityGraph ("פוסט-ישות-גרף-עם-משתמשים-תגובה"); CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder (); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery (Post.class); שורש שורש = criteriaQuery.from (Post.class); criteriaQuery.where (criteriaBuilder.equal (root.get ("id"), id)); TypedQuery typedQuery = entityManager.createQuery (criteriaQuery); typedQuery.setHint ("javax.persistence.loadgraph", entityGraph); פוסט פוסט = typedQuery.getSingleResult ();

בכל אחד מאלה, סוג הגרף ניתן כרמז. בעוד שבדוגמה הראשונה השתמשנו ב- מַפָּה, בשתי הדוגמאות המאוחרות יותר השתמשנו ב- setHint () שיטה.

7. מסקנה

במאמר זה, בדקנו באמצעות גרף הישות של JPA כדי להשיג דינמית יֵשׁוּת ועמותותיה.

ההחלטה מתקבלת בזמן ריצה בו אנו בוחרים לטעון או לא את הקשר הקשור.

ביצועים הם ללא ספק גורם מפתח שיש לקחת בחשבון בעת ​​תכנון גופי JPA. תיעוד JPA ממליץ להשתמש ב- FetchType.LAZY אסטרטגיה במידת האפשר, ואת גרף הישות כאשר אנו צריכים לטעון אסוציאציה.

כרגיל, כל הקוד זמין ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found