סוגי שאילתות JPA

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

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

2. התקנה

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

@Table (name = "משתמשים") @Entity מחלקת ציבור UserEntity {@Id פרטי מזהה ארוך; שם מחרוזת פרטי; // קונסטרוקטור סטנדרטי, גטרים וקובעים. }

ישנם שלושה סוגים בסיסיים של שאילתות JPA:

  • שאילתא, כתוב בתחביר Java Persistence Query Language (JPQL)
  • NativeQuery, כתוב בתחביר SQL רגיל
  • שאילתת ממשק API, נבנה באופן פרוגרמטי בשיטות שונות

בואו נחקור אותם.

3. שאילתא

א שאילתא דומה בתחביר ל- SQL, והוא משמש בדרך כלל לביצוע פעולות CRUD:

UserEntity ציבורי getUserByIdWithPlainQuery (מזהה ארוך) {Query jpqlQuery = getEntityManager (). createQuery ("בחר U מ- UserEntity u WHERE u.id =: id"); jpqlQuery.setParameter ("id", id); return (UserEntity) jpqlQuery.getSingleResult (); }

זֶה שאילתא מאחזר את רשומת ההתאמה מה- משתמשים טבלה וגם ממפה אותה אל UserEntity לְהִתְנַגֵד.

יש שתיים נוספות שאילתא תת-סוגים:

  • TypedQuery
  • NamedQuery

בואו נראה אותם בפעולה.

3.1. TypedQuery

עלינו לשים לב ל לַחֲזוֹר הצהרה בדוגמה הקודמת שלנו. JPA לא יכול להסיק מה שאילתא סוג התוצאה יהיה, וכתוצאה מכך עלינו ללהק.

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

בוא נראה TypedQuery אלטרנטיבה, בהשוואה לדוגמא הראשונה שלנו:

UserEntity ציבורי getUserByIdWithTypedQuery (מזהה ארוך) {TypedQuery typedQuery = getEntityManager (). createQuery ("בחר u מתוך UserEntity u WHERE u.id =: id", UserEntity.class); typedQuery.setParameter ("id", id); להחזיר typedQuery.getSingleResult (); }

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

3.2. NamedQuery

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

JPA גם הסיקו אותנו עם אחר שאילתא תת-סוג המכונה a NamedQuery.

אנו מגדירים NamedQuery על יֵשׁוּת הכיתה עצמה, ומספקת דרך מרוכזת, מהירה וקלה לקרוא ולמצוא יֵשׁוּתשאילתות קשורות.

את כל NamedQueries חייב להיות שם ייחודי.

בואו נראה איך נוכל להוסיף א NamedQuery שלנו UserEntity מעמד:

@Table (name = "users") @Entity @NamedQuery (name = "UserEntity.findByUserId", query = "בחר u מתוך UserEntity u WHERE u.id =: userId") UserEntity ברמה ציבורית {@ Id פרטי מזהה ארוך; שם מחרוזת פרטי; // קונסטרוקטור סטנדרטי, גטרים וקובעים. }

ה @NamedQuery הערה צריכה להיות מקובצת בתוך a @NamedQueries ביאור אם אנו משתמשים ב- Java לפני גרסה 8. מ- Java 8 ואילך, אנו יכולים פשוט לחזור על ה- @NamedQuery ביאור אצלנו יֵשׁוּת מעמד.

באמצעות א NamedQuery מאוד פשוט:

UserEntity ציבורי getUserByIdWithNamedQuery (מזהה ארוך) {Query namedQuery = getEntityManager (). createNamedQuery ("UserEntity.findByUserId"); בשםQuery.setParameter ("userId", id); להחזיר (UserEntity) בשםQuery.getSingleResult (); }

4. NativeQuery

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

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

בואו נראה כיצד להשתמש ב- NativeQuery שמניבה את אותן תוצאות כמו הדוגמאות הקודמות שלנו:

UserEntity ציבורי getUserByIdWithNativeQuery (מזהה ארוך) {Query nativeQuery = getEntityManager (). createNativeQuery ("בחר * מתוך משתמשים WHERE id =: userId", UserEntity.class); nativeQuery.setParameter ("userId", id); להחזיר (UserEntity) nativeQuery.getSingleResult (); }

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

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

5. קריטריונים שאילתת API

קריטריונים שאילתות API הן שאילתות הבנויות בתכנות ובטוחות לסוג - דומות במקצת לשאילתות JPQL בתחביר:

UserEntity ציבורי getUserByIdWithCriteriaQuery (מזהה ארוך) {CriteriaBuilder criteriaBuilder = getEntityManager (). getCriteriaBuilder (); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery (UserEntity.class); שורש userRoot = criteriaQuery.from (UserEntity.class); UserEntity queryResult = getEntityManager (). CreateQuery (criteriaQuery.select (userRoot) .where (criteriaBuilder.equal (userRoot.get ("id"), id))) .getSingleResult (); החזר queryResult; }

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

6. מסקנה

במאמר מהיר זה למדנו מהן שאילתות JPA, יחד עם השימוש בהן.

שאילתות JPA הן דרך נהדרת להפשט את ההיגיון העסקי שלנו משכבת ​​הגישה לנתונים שלנו, שכן אנו יכולים להסתמך על תחביר JPQL ולתת לספק JPA שלנו לבחירה לטפל שאילתא תִרגוּם.

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


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