שאילתת שם שינה

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

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

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

במאמר זה נראה כיצד להגדיר ולהשתמש בשאילתות עם שם שינה באמצעות ה- @NamedQuery ו @NamedNativeQuery ביאורים.

2. הישות

בואו נסתכל תחילה על הישות בה נשתמש במאמר זה:

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

בדוגמה שלנו, אנו נאחזר עובד על סמך מספר העובד שלהם.

3. שאילתה בשם

כדי להגדיר זאת כשאילתה בשם, נשתמש ב- org.hibernate.annotations.NamedQuery ביאור. זה מאריך את הג'אווה.persistence.NamedQuery עם תכונות שינה.

נגדיר זאת כהערה של ה- עובד המחלקה מעמד:

@ org.hibernate.annotations.NamedQuery (name = "DeptEmployee_findByEmployeeNumber", שאילתה = "מ- DeptEmployee שבו עובד מספר =: עובד לא") 

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

אם יש לנו יותר משאילתה אחת בשם ישות, נשתמש ב- @NamedQueries ביאור לקבוצת אלה:

@ org.hibernate.annotations.NamedQueries ({@ org.hibernate.annotations.NamedQuery (name = "DeptEmployee_FindByEmployeeNumber", query = "from DeptEmployee where employeeNumber =: employeeNo"), @ org.hibernate.annotations (Name.NamedQ) DeptEmployee_FindAllByDesgination ", query =" from DeptEmployee where designation =: designation "), @ org.hibernate.annotations.NamedQuery (name =" DeptEmployee_UpdateEmployeeDepartment ", שאילתה =" עדכן מחלקת הגדרת DeptEmployee = עובד: שם: עובד. ..})

שים לב ששאילתת HQL יכולה להיות פעולה בסגנון DML. אז זה לא צריך להיות א בחר הצהרה בלבד. לדוגמה, נוכל לקבל שאילתת עדכון כמו ב- DeptEmployee_UpdateEmployeeDesignation מֵעַל.

3.1. קביעת תצורה של תכונות שאילתה

אנו יכולים להגדיר תכונות שאילתה שונות באמצעות @NamedQuery ביאור. בואו נסתכל על דוגמה:

@ org.hibernate.annotations.NamedQuery (name = "DeptEmployee_FindAllByDepartment", query = "from DeptEmployee where department =: department", פסק זמן = 1, fetchSize = 10)

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

  • ניתן למטבח - האם השאילתה (תוצאות) ניתנת לשמירה או לא
  • cacheMode - מצב המטמון המשמש לשאילתה זו; זה יכול להיות אחד מ קבל, התעלם, נורמלי, שים, אוֹ לְרַעֲנֵן
  • מטמון אזור - אם תוצאות השאילתה ניתנות לשמירה, שם לאזור מטמון השאילתה לשימוש
  • תגובה - הערה שנוספה לשאילתת SQL שנוצרה; ממוקד ל- DBA
  • flushMode - מצב ההדחה לשאילתה זו, אחד של תמיד, אוטומטי, התחייבות, ידני, אוֹ PERSISTENCE_CONTEXT

3.2. שימוש בשאילתה בשם

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

שאילתת שאילתה = session.createNamedQuery ("DeptEmployee_FindByEmployeeNumber", DeptEmployee.class); query.setParameter ("עובד לא", "001"); תוצאת DeptEmployee = query.getSingleResult (); 

הנה, השתמשנו ב- createNamedQuery שיטה. זה לוקח את שם השאילתה ומחזיר org.hibernate.query.Query לְהִתְנַגֵד.

4. שם שאילתה מקורית

כמו גם שאילתות HQL, אנו יכולים גם להגדיר SQL מקורי כשאילתה בשם. לשם כך נוכל להשתמש ב- @NamedNativeQuery ביאור. למרות שזה דומה ל- @NamedQuery, זה דורש קצת יותר תצורה.

בואו נחקור את ההערה באמצעות דוגמה:

@ org.hibernate.annotations.NamedNativeQueries (@ org.hibernate.annotations.NamedNativeQuery (name = "DeptEmployee_GetEmployeeByName", query = "select * from deptemployee emp where name =: name", resultClass = DeptEmployee.class))

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

דרך נוספת למפות את התוצאות היא להשתמש ב- resultSetMapping תכונה. כאן נוכל לציין את שם ההגדרה המוגדרת מראש SQLResultSetMapping.

שים לב שאנחנו יכולים להשתמש רק באחד מ- resultClass ו resultSetMapping.

4.1. שימוש בשאילתת הילידים בשם

כדי להשתמש בשאילתת הילידים שצוינה, נוכל להשתמש ב- Session.createNamedQuery ():

שאילתת שאילתה = session.createNamedQuery ("DeptEmployee_FindByEmployeeName", DeptEmployee.class); query.setParameter ("שם", "ג'ון וויין"); תוצאת DeptEmployee = query.getSingleResult ();

או ה Session.getNamedNativeQuery ():

שאילתת NativeQuery = session.getNamedNativeQuery ("DeptEmployee_FindByEmployeeName"); query.setParameter ("שם", "ג'ון וויין"); תוצאת DeptEmployee = (DeptEmployee) query.getSingleResult ();

ההבדל היחיד בין שתי הגישות הללו הוא סוג ההחזרה. הגישה השנייה מחזירה א NativeQuery, שהיא תת מחלקה של שאילתא.

5. נהלים ופונקציות מאוחסנים

אנחנו יכולים להשתמש ב- @NamedNativeQuery ביאור להגדרת שיחות גם לנהלים ולפונקציות המאוחסנים:

@ org.hibernate.annotations.NamedNativeQuery (name = "DeptEmployee_UpdateEmployeeDesignation", query = "call UPDATE_EMPLOYEE_DESIGNATION (: employeeNumber,: newDesignation)", resultClass = DeptEmployee.class)

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

6. מסקנה

במאמר זה ראינו כיצד להגדיר ולהשתמש ב- HQL בשם ושאילתות מקוריות.

קוד המקור זמין ב- GitHub.