מאגרי מידע המיועדים לאביב

1. הקדמה

כאשר מדגמנים מערכת או תהליך בעולם האמיתי, מאגרים בסגנון DDD (מונעי עיצוב) הם אפשרות טובה. בדיוק למטרה זו אנו יכולים להשתמש ב- Spring Data JPA כשכבת ההפשטה שלנו לגישה לנתונים.

אם אתה חדש במושג זה, עיין במדריך ההיכרות הזה כדי לעזור לך להתמצא במהירות.

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

2. תלות Maven

האפשרות ליצור מאגרים להלחנה זמינה החל באביב 5.

בואו נוסיף את התלות הנדרשת ל- JPA של נתוני אביב:

 org.springframework.data spring-data-jpa 2.2.2.RELEASE 

נצטרך גם להגדיר מקור נתונים על מנת ששכבת הגישה לנתונים שלנו תפעל. מומלץ להקים בסיס נתונים בזיכרון כמו H2 לפיתוח ובדיקה מהירה.

3. רקע

3.1. שינה במצב יישום JPA

Spring Data JPA, כברירת מחדל, משתמש ב- Hibernate כהטמעת JPA. אנו יכולים בקלות לבלבל אחד את השני או להשוות ביניהם, אך הם משרתים מטרות שונות.

Spring Data JPA היא שכבת ההפשטה של ​​גישה לנתונים שמתחתיה נוכל להשתמש בכל יישום. נוכל למשל לכבות את מצב שינה לטובת EclipseLink.

3.2. מאגרי ברירת מחדל

בהרבה מקרים לא נצטרך לכתוב שאילתות בעצמנו.

במקום זאת, עלינו ליצור ממשקים אשר בתורם מרחיבים את ממשקי מאגר הנתונים הגנריים של האביב:

ממשק ציבורי LocationRepository מרחיב את JpaRepository {}

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

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

ממשק ציבורי StoreRepository מרחיב את JpaRepository {List findStoreByLocationId (Long locationId); }

3.3. מאגרים מותאמים אישית

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

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

ממשק ציבורי ItemTypeRepository מרחיב את JpaRepository, CustomItemTypeRepository {}

פה CustomItemTypeRepository הוא ממשק נוסף:

ממשק ציבורי CustomItemTypeRepository {void deleteCustomById (ישות ItemType); }

היישום שלה יכול להיות מאגר מכל סוג שהוא, ולא רק JPA:

מחלקה ציבורית CustomItemTypeRepositoryImpl מיישם CustomItemTypeRepository {@Autowired פרטי EntityManager entityManager; @Override public void deleteCustomById (ItemType itemType) {entityManager.remove (itemType); }}

אנחנו רק צריכים לוודא שיש בו את התיקון יישום. עם זאת, אנו יכולים לקבוע תיקון מותאם אישית באמצעות תצורת ה- XML ​​הבאה:

או באמצעות הערה זו:

@EnableJpaRepositories (basePackages = "com.baeldung.repository", repositoryImplementationPostfix = "CustomImpl")

4. הרכבת מאגרים באמצעות שברים מרובים

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

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

עכשיו עם אביב 5, יש לנו אפשרות העשר את מאגר ה- JPA שלנו במאגרים מרובים של קטעים. שוב, הדרישה נותרה כי יהיו לנו שברים אלה כזוגי יישום ממשק.

כדי להדגים זאת, בואו ניצור שני שברים:

ממשק ציבורי CustomItemTypeRepository {void deleteCustom (ישות ItemType); בטל findThenDelete (מזהה ארוך); } ממשק ציבורי CustomItemRepository {Item findItemById (מזהה ארוך); בטל deleteCustom (ישות פריט); בטל findThenDelete (מזהה ארוך); }

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

ממשק ציבורי ItemTypeRepository מרחיב את JpaRepository, CustomItemTypeRepository, CustomItemRepository {}

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

5. התמודדות עם עמימות

מכיוון שאנו עוברים בירושה ממאגרים מרובים, אנו עשויים להתקשות להבין אילו מהיישומים שלנו ישמשו במקרה של התנגשות. למשל, בדוגמה שלנו, לשני מאגרי השברים יש שיטה, findThenDelete (), עם אותה חתימה.

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

אנו יכולים לבדוק זאת באמצעות מקרה הבדיקה הבא:

@Test הציבור בטל givenItemAndItemTypeWhenDeleteThenItemTypeDeleted () {OptionType = optionalRepository.findById (1L) אופציונלי; assertTrue (itemType.isPresent ()); פריט פריט = wroteRepository.findItemById (2L); assertNotNull (פריט); wroteRepository.findThenDelete (1L); אופציונלי sameItemType = wroteRepository.findById (1L); assertFalse (sameItemType.isPresent ()); פריט sameItem = wroteRepository.findItemById (2L); assertNotNull (sameItem); }

6. מסקנה

במאמר זה בדקנו את הדרכים השונות בהן אנו יכולים להשתמש במאגרי Spring Data JPA. ראינו ש- Spring עושה את זה פשוט לבצע פעולות בסיס נתונים באובייקטים של התחום שלנו בלי לכתוב הרבה קוד או אפילו שאילתות SQL.

תמיכה זו ניתנת להתאמה אישית ניכרת באמצעות מאגרים ניתנים להלחנה.

קטעי הקוד ממאמר זה זמינים כפרויקט Maven כאן ב- GitHub.