מבוא לג'ינק עם אביב

1. הקדמה

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

2. תלות Maven

נצטרך להוסיף את התלות של ג'ינק ב pom.xml קוֹבֶץ:

 org.jinq jinq-jpa 1.8.22 

לקראת האביב, נוסיף את תלות ה- ORM באביב pom.xml קוֹבֶץ:

 org.springframework spring-orm 5.2.5.RELEASE 

לבסוף, לבדיקה נשתמש במסד נתונים H2 בזיכרון, אז בואו נוסיף גם תלות זו, יחד עם spring-boot-starter-data-jpa לקובץ pom.xml:

 com.h2database h2 1.4.200 org.springframework.boot spring-boot-starter-data-jpa 2.2.6.RELEASE 

3. הבנת ג'ינק

Jinq עוזר לנו לכתוב שאילתות בסיסיות קלות וקריאות יותר על ידי חשיפת ממשק API שוטף שמבוסס על פנימיות ה- API של Java Stream.

בואו נראה דוגמה שבה אנחנו מסננים מכוניות לפי דגם:

jinqDataProvider.streamAll (entityManager, Car.class) .where (c -> c.getModel (). שווה (מודל)). toList ();

Jinq מתרגם את קטע הקוד לעיל לשאילתת SQL בצורה יעילה, כך שהשאילתה הסופית בדוגמה זו תהיה:

בחר c. * ממכונית c איפה c.model =?

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

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

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

3.1. מגבלות

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

לכן, איננו יכולים לצפות מהכלי לתרגם כל סוג מותאם אישית או את כל השיטות מסוג זה.

3.2. סוגי נתונים נתמכים

בואו נראה את סוגי הנתונים והשיטות הנתמכים הנתמכים:

  • חוּטשווים(), בהשוואה ל() שיטות בלבד
  • סוגי נתונים פרימיטיביים - פעולות חשבון
  • Enums ושיעורים מותאמים אישית - תומכים בפעולות == ו-! = בלבד
  • java.util.Collection - מכיל ()
  • תַאֲרִיך API - שווים(), לפני(), לאחר() שיטות בלבד

הערה: אם נרצה להתאים אישית את ההמרה מאובייקט Java לאובייקט מסד נתונים, נצטרך לרשום את היישום הקונקרטי שלנו של AttributeConverter בג'ינק.

4. שילוב ג'ינק עם אביב

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

4.1. ממשק מאגר

אביב משתמש במושג מאגרים לניהול ישויות. בואו נסתכל על שלנו מאגר רכב ממשק שבו יש לנו שיטה לאחזור a אוטו לדגם נתון:

ממשק ציבורי CarRepository {findByModel אופציונלי (מודל מחרוזת); }

4.2. מאגר בסיס מופשט

הַבָּא, נצטרך מאגר בסיס לספק את כל יכולות ג'ינק:

מחלקה מופשטת ציבורית BaseJinqRepositoryImpl {@ פרטית אוטומטית JinqJPAStreamProvider jinqDataProvider; @PersistenceContext EntityManager entityManager פרטי; מופשט מוגן ישות ClassType (); זרם JPAJinqStream ציבורי () {return streamOf (entityType ()); } מוגן על JPAJinqStream streamOf (Class clazz) {return jinqDataProvider.streamAll (entityManager, clazz); }}

4.3. יישום המאגר

עכשיו כל מה שאנחנו צריכים עבור ג'ינק הוא EntityManager מופע ומחלקת סוג הישות.

בוא נראה את אוטו יישום מאגר באמצעות מאגר הבסיס של ג'ינק שהגדרנו זה עתה:

@Repository public class CarRepositoryImpl מרחיב את BaseJinqRepositoryImpl מיישם את CarRepository {@Override public אופציונלי findByModel (מודל מחרוזת) {return stream () .where (c -> c.getModel (). שווה (מודל)) .findFirst (); } @Override מוגן Class entityType () {להחזיר Car.class; }}

4.4. חיווט JinqJPAStreamProvider

על מנת לחבר את JinqJPAStreamProvider למשל, אנחנו הוסף את תצורת ספק ה- Jinq:

@ תצורה בכיתה ציבורית JinqProviderConfiguration {@Bean @Autowired JinqJPAStreamProvider jinqProvider (EntityManagerFactory emf) {להחזיר JinqJPAStreamProvider חדש (emf); }}

4.5. קביעת תצורה של יישום האביב

השלב האחרון הוא הגדר את אפליקציית האביב שלנו באמצעות מצב שינה והגדרת התצורה שלנו. כהפניה, ראה שלנו application.properties קובץ, שבו אנו משתמשים במופע H2 בזיכרון כמסד הנתונים:

spring.datasource.url = jdbc: h2: ~ / jinq spring.datasource.username = sa spring.datasource.password = spring.jpa.hibernate.ddl-auto = create-drop

5. מדריך שאילתות

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

5.1. איפה

ה איפה סעיף מאפשר החלת מסננים מרובים על איסוף נתונים.

בדוגמה הבאה, אנו רוצים לסנן מכוניות לפי דגם ותיאור:

stream (). Where (c -> c.getModel (). שווה (model) && c.getDescription (). מכיל (desc)). toList ();

וזה ה- SQL שמתרגם ג'ינק:

בחר c.model, c. תיאור ממכונית c איפה c.model =? ולאתר (?, c. תיאור)> 0

5.2. בחר

במקרה שאנחנו רוצים לאחזר רק כמה עמודות / שדות ממסד הנתונים, עלינו להשתמש ב- בחר סָעִיף.

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

stream () .select (c -> Tuple3 new (c.getModel (), c.getYear (), c.getEngine ())). toList ()

וה- SQL המתורגם:

בחר c.model, c.year, c.motor ממכונית c

5.3. מצטרף

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

לדוגמה, אם נוסיף את ישות היצרן ב- אוטו:

@Entity (name = "CAR") רכב בכיתה ציבורית {// ... @OneToOne @JoinColumn (name = "name") ציבורי יצרן getManufacturer () {יצרן החזרה; }}

וה יַצרָן ישות עם רשימת אוטוs:

@Entity (name = "MANUFACTURER") יצרן מחלקה ציבורית {// ... @OneToMany (mappedBy = "model") ציבורי רשימה getCars () {מכוניות חוזרות; }}

כעת אנו יכולים להשיג את יַצרָן לדגם נתון:

יצרן אופציונלי = stream (). Where (c -> c.getModel (). שווה (דגם)). בחר (c -> c.getManufacturer ()) .findFirst ();

כצפוי, ג'ינק ישתמש בסעיף SQL להצטרף פנימי בתרחיש הזה:

בחר m.name, m.city ממכונית c יצרן להצטרף פנימי m ב- c.name = m.name איפה c.model =?

במקרה שנצטרך להיות יותר שליטה על ה- לְהִצְטַרֵף סעיפים על מנת ליישם קשרים מורכבים יותר על פני הישויות, כמו יחס של רבים לרבים, אנו יכולים להשתמש ב- לְהִצְטַרֵף שיטה:

רשימה list = streamOf (Manufacturer.class) .join (m -> JinqStream.from (m.getCars ())) .toList ()

לבסוף נוכל להשתמש בסעיף SQL להצטרף חיצוני שמאלי באמצעות ה- leftOuterJoin שיטה במקום לְהִצְטַרֵף שיטה.

5.4. צבירות

כל הדוגמאות שהצגנו עד כה משתמשות ב- למנות או ה findFirst שיטות - להחזרת התוצאה הסופית של שאילתתנו ב- Jinq.

מלבד שיטות אלה, יש לנו גם גישה לשיטות אחרות לצבירת תוצאות.

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

סה"כ ארוך = זרם (). איפה (c -> c.getModel (). שווה (מודל)). count ()

ו- SQL הסופי משתמש ב- לספור שיטת SQL כצפוי:

בחר ספירה (c.model) ממכונית c איפה c.model =?

ג'ינק מספקת גם שיטות צבירה כמו סְכוּם, מְמוּצָע, דקה, מקסימום, וה אפשרות לשלב צבירות שונות.

5.5. דִפּוּף

במקרה שאנחנו רוצים לקרוא נתונים בקבוצות, נוכל להשתמש ב- לְהַגבִּיל ו לדלג שיטות.

בואו נראה דוגמה בה אנו רוצים לדלג על 10 המכוניות הראשונות ולקבל רק 20 פריטים:

stream () .skip (10) .limit (20) .toList ()

ו- SQL שנוצר הוא:

בחר c. * ממגבלת c לרכב? קיזוז?

6. מסקנה

הנה. במאמר זה ראינו גישה להגדרת יישום Spring עם Jinq באמצעות Hibernate (באופן מינימלי).

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

כמו תמיד, ניתן למצוא את המקורות באתר GitHub.


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