מיון עם שינה
1. סקירה כללית
מאמר זה ממחיש כיצד למיין עם מצב שינה, תוך שימוש בשפת השאילתות החיובית (HQL) והן ב- Criteria API.
2. מיון עם HQL
מיון ב- HQL של Hibernate פשוט כמו הוספת ה- מיין לפי סעיף למחרוזת שאילתת HQL:
מחרוזת hql = "FROM Foo f סדר לפי f.name"; שאילתת שאילתות = sess.createQuery (hql);
לאחר ביצוע קוד זה, מצב שינה ייצור את שאילתת SQL הבאה:
שינה: בחר foo0_.ID כ- ID1_0_, foo0_.NAME כ- NAME2_0_ מ- FOO foo0_ סדר לפי foo0_.NAME
כיוון ברירת המחדל של סדר מיון עולה. זו הסיבה שתנאי ההזמנה, עלייה, אינו נכלל בשאילתת SQL שנוצרה.
2.1. שימוש בסדר מיון מפורש
כדי לציין את סדר המיון באופן ידני - יהיה עליך לכלול את כיוון ההזמנה ב- HQL מחרוזת שאילתה:
מחרוזת hql = "FROM FOO f סדר לפי f.name ASC"; שאילתת שאילתות = sess.createQuery (hql);
בדוגמה זו, הגדרת ה- עלייה סעיף ב- HQL נכלל בשאילתת SQL שנוצרה:
שינה: בחר foo0_.ID כ- ID1_0_, foo0_.NAME כ- NAME2_0_ מ- FOO foo0_ סדר לפי foo0_.NAME ASC
2.2. ממיין לפי מאפיין יותר מאשר אחד
ניתן להוסיף תכונות מרובות, יחד עם סדר מיון אופציונלי מיין לפי סעיף במחרוזת שאילתת HQL:
מחרוזת hql = "FROM Foo f סדר לפי f.name DESC, f.id ASC"; שאילתת שאילתות = sess.createQuery (hql);
שאילתת SQL שנוצרה תשתנה בהתאם:
שינה: בחר foo0_.ID כ- ID1_0_, foo0_.NAME כ- NAME2_0_ מ- FOO foo0_ סדר לפי foo0_.NAME DESC, foo0_.ID ASC
2.3. הגדרת עדיפות מיון של ערכים אפסיים
כברירת מחדל, כאשר לתכונה למיין יש ריק ערכים, על RDMS להחליט על עדיפותם. ניתן לבטל טיפול ברירת מחדל זה על ידי הצבה א אפסים ראשונים אוֹ אפסים אחרונים סעיף במחרוזת שאילתת HQL.
דוגמה פשוטה זו מציבה כל אפס בסוף רשימת התוצאות:
מחרוזת hql = "FROM Foo f סדר לפי f.name NULLS LAST"; שאילתת שאילתות = sess.createQuery (hql);
בוא נראה את הוא null ואז 1 אחר 0 סעיף ב שאילתת SQL שנוצרה:
שינה: בחר foo0_.ID כ- ID1_1_, foo0_.NAME כ- NAME2_1_, foo0_.BAR_ID כ- BAR_ID3_1_, foo0_.idx כ- idx4_1_ מ- FOO foo0_ סדר לפי מקרה כאשר foo0_.NAME הוא ריק ואז 1 אחר 0 סיום, foo0_.NAME
2.4. מיון יחסים מרובים
מאפשר לנתח מקרה מיון מורכב: מיון ישויות ביחס של יחס אחד לרבים – בָּר המכיל אוסף של פו ישויות.
נעשה זאת על ידי הערת האוסף עם תרדמת החורף @מיין לפי ביאור; נפרט את השדה שלפיו מתבצעת ההזמנה, וכן את הכיוון:
@OrderBy (clause = "NAME DESC") הגדר fooList = חדש HashSet ();
שים לב ש סָעִיף טיעון להערה. זה ייחודי למצב שינה @מיין לפיבהשוואה לדומה @מיין לפי ביאור JPA. מאפיין נוסף המבדיל גישה זו מהמקבילה שלה ל- JPA הוא כי ה- סָעִיף הטיעון מצביע על כך שהמיון נעשה על פי ה- שֵׁם העמודה של FOO שולחן, לא על שֵׁם תכונה של פו.
עכשיו בואו נסתכל על המיון בפועל סורגים ו פוס:
מחרוזת hql = "FROM Bar b סדר לפי b.id"; שאילתת שאילתות = sess.createQuery (hql);
ה משפט SQL שנוצר מראה כי הממוינים פו ממוקמים ב fooList:
שינה: בחר bar0_.ID כ- ID1_0_, bar0_.NAME כ- NAME2_0_ מ- BAR bar0_ סדר לפי bar0_.ID שינה: בחר שוטה0_.BAR_ID כ- BAR_ID3_0_0_, טיפש0_.ID כ- ID1_1_0_, טיפש0_.ID כ- ID1_1_1_. .BAR_ID כ- BAR_ID3_1_1_, טיפש0_.idx כ- idx4_1_1_ מ- FOO שוטים0_ איפה שוטים0_.BAR_ID =? סדר על ידי שוטה 0_.NAME
דבר אחד שיש לזכור הוא שכן לא ניתן למיין רשימות כמו שהיה עם JPA. בתיעוד למצב שינה קובע:
“מצב שינה עכשיו מתעלם מ- @ OrderBy ב- @ ElementCollection למשל. רשימה. סדר האלמנטים הוא כפי שהוחזר על ידי מסד הנתונים, לא מוגדר. "
כהערה צדדית, ניתן יהיה לעקוף את המגבלה הזו על ידי שימוש בתצורת XML מדור קודם למצב שינה, ולהחליף את אלמנט עם a אֵלֵמֶנט.
3. מיון בקריטריונים של שינה
ה- Criteria Object API מספק את ה- להזמין בכיתה כ- API הראשי לניהול המיון.
3.1. קביעת סדר המיון
ה להזמין בכיתה יש שתי שיטות להגדרת סדר המיון:
- עלייה(תכונת מחרוזת) : ממיין את השאילתה לפי תְכוּנָה בסדר עולה.
- ירידה(תכונת מחרוזת) : ממיין את השאילתה לפי תְכוּנָה בסדר יורד.
נתחיל בדוגמה פשוטה - מיון לפי יחיד תְעוּדַת זֶהוּת תְכוּנָה:
קריטריונים לקריטריונים = sess.createCriteria (Foo.class, "FOO"); criteria.addOrder (Order.asc ("id"));
שים לב שהוויכוח ל עלייה השיטה רגישה לאותיות רישיות ועליה להתאים ל שֵׁם של התכונה למיין לפי.
ה- API של אובייקט ה- Hibernate Criteria קובע במפורש כיוון סדר מיון וזה בא לידי ביטוי במשפט SQL שנוצר על ידי הקוד:
תרדמת שינה: בחר this_.ID כ- ID1_0_0_, this_.NAME כ- NAME2_0_0_ מתוך FOO זה_ סדר לפי שקית_.ID זו
3.2. מיון לפי מאפיין יותר מאחד
מיון לפי מספר מאפיינים מחייב רק הוספת להזמין התנגדות ל קריטריונים למשל, כמו בדוגמה שלהלן:
קריטריונים לקריטריונים = sess.createCriteria (Foo.class, "FOO"); criteria.addOrder (Order.asc ("שם")); criteria.addOrder (Order.asc ("id"));
השאילתה שנוצרת ב- SQL היא:
מצב שינה: בחר את זה_יד כ- ID1_0_0_, את_השם הזה כ- NAME2_0_0_ מ- FOO זה_ סדר על ידי זה_.נאם asc, זה_.ID שק
3.3. הגדרת עדיפות מיון של ערכים אפסיים
כברירת מחדל, כאשר לתכונה למיין יש ריק ערכים, על RDMS להחליט על עדיפותם. ממשק ה- API של אובייקט Hibernate Criteria מקל על שינוי ברירת המחדל במקום אפסים בסוף של רשימה מסודרת עולה:
קריטריונים לקריטריונים = sess.createCriteria (Foo.class, "FOO"); criteria.addOrder (Order.asc ("שם"). nulls (NullPrecedence.LAST));
הנה הבסיס SQL שאילתה - עם הוא null ואז 1 אחר 0 סָעִיף:
מצב שינה: בחר את זה_יד כ- ID1_1_1_, את_השם הזה כ- NAME2_1_1_, זה_. BAR_ID כ- BAR_ID3_1_1_, this_.idx כ- idx4_1_1_, bar2_.ID כ- ID1_0_0_, bar2_.NAME כ- NAME2_0_0_ מ- FOON לפי מקרה אז זה. עוד 1 0 סיום, this_.NAME עולה
לחלופין, אנו יכולים גם הצב את האפסים בהתחלה של רשימה מסודרת יורדת:
קריטריונים לקריטריונים = sess.createCriteria (Foo.class, "FOO"); criteria.addOrder (Order.desc ("שם"). nulls (NullPrecedence.FIRST));
שאילתת SQL המתאימה עוקבת אחריה - עם הוא null ואז 0 אחר 1 סָעִיף:
שינה: בחר את זה_יד כ- ID1_1_1_, את_השם הזה כ- NAME2_1_1_, את זה.- BAR_ID כ- BAR_ID3_1_1_, את זה.- idx כ- idx4_1_1_, את bar2_.ID כ- ID1_0_0_, bar2_.NAME כ- NAME2_0_0_ מ- FOON לפי המקרה כאשר זה 0 אחר קצה אחד, זה_.NAME
ציין זאת, אם התכונה למיין לפי היא סוג פרימיטיבי כמו int, א חריג נוכחות ייזרק.
לדוגמא, אם הערך של f.anIntVariable הוא אפס, ואז ביצוע השאילתה:
מחרוזת jql = "בחר f מ Foo כסדר f לפי f.anIntVariable desc NULLS FIRST"; שאילתה sortQuery = entityManager.createQuery (jql);
ישליך:
javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: ערך אפס הוקצה למאפיין מגדיר סוג פרימיטיבי של com.cc.jpa.example.Foo.anIntVariable
4. מסקנה
מאמר זה בוחן מיון עם Hibernate - שימוש בממשקי ה- API הזמינים עבור ישויות פשוטות וכן עבור ישויות ביחס של אחד לרבים.
ניתן למצוא את היישום של מדריך מיון למצב שינה זה בפרויקט github - זהו פרויקט מבוסס ליקוי חמה, כך שיהיה קל לייבא ולהפעיל אותו כפי שהוא.