מדריך ל- EntityManager Hibernate

1. הקדמה

EntityManager הוא חלק מממשק ה- API של Java Persistence. בעיקר, היא מיישמת את ממשקי התכנות וכללי מחזור החיים המוגדרים במפרט JPA 2.0.

יתר על כן, אנו יכולים לגשת להקשר ההתמדה באמצעות ממשקי ה- API ב- EntityManager.

במדריך זה נבחן את התצורה, הסוגים וממשקי ה- API השונים של ה- EntityManager.

2. תלות Maven

ראשית, עלינו לכלול את התלות של מצב שינה:

 org.hibernate hibernate-core 5.4.0.Final 

נצטרך לכלול גם את תלות הנהג, תלוי במסד הנתונים בו אנו משתמשים:

 mysql mysql-connector-java 8.0.13 

התלות של ליבת שינה ו- mysql-connector-java זמינות ב- Maven Central.

3. תצורה

עכשיו, בואו נדגים את EntityManager, באמצעות א סרט ישות המתאימה לטבלת MOVIE במסד הנתונים.

במהלך מאמר זה נשתמש ב- EntityManager ממשק API לעבודה עם סרט אובייקטים במסד הנתונים.

3.1. הגדרת הישות

נתחיל ביצירת היישות המתאימה לטבלת MOVIE, באמצעות ה- @יֵשׁוּת ביאור:

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

3.2. ה התמדה.קסמל קוֹבֶץ

כאשר EntityManagerFactory נוצר, יישום ההתמדה מחפש את META-INF / persistence.xml הקובץ בכביש.

קובץ זה מכיל את התצורה של ה- EntityManager:

 Hibernate EntityManager הדגמה com.baeldung.hibernate.pojo.Movie נכון 

כדי להסביר, אנו מגדירים את יחידת ההתמדה המציינת את מאגר הנתונים הבסיסי המנוהל על ידי EntityManager.

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

4. מיכל ויישומים מנוהלים EntityManager

בעיקרון, ישנם שני סוגים של EntityManager: מנוהל על ידי מיכל ומנוהל על ידי יישום.

בואו נסתכל מקרוב על כל סוג.

4.1. מנוהל על ידי מיכל EntityManager

הנה, המכולה מזריקה את EntityManager ברכיבי הארגון שלנו.

במילים אחרות, המכולה יוצרת את EntityManager מ ה EntityManagerFactory בשבילנו:

@PersistenceContext EntityManager entityManager; 

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

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

4.2. ניהול היישומים EntityManager

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

למעשה, ניצור את ה- EntityManager. יתר על כן, אנו גם ננהל את מחזור החיים של ה- EntityManager יצרנו.

ראשית, בואו ניצור את EntityManagerFactory:

EntityManagerFactory emf = Persistence.createEntityManagerFactory ("com.baeldung.movie_catalog");

על מנת ליצור EntityManager, עלינו להתקשר במפורש createEntityManager () בתוך ה EntityManagerFactory:

EntityManager סטטי ציבורי getEntityManager () {return emf.createEntityManager (); }

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

4.3. חוט-בטיחות

ה EntityManagerFactory מקרים, וכתוצאה מכך, מצב שינה SessionFactory מקרים, הם בטוחים בחוטים. אז זה בטוח לחלוטין בהקשרים בו זמנית לכתוב:

EntityManagerFactory emf = // נאסף מאיפה שהוא EntityManager em = emf.createEntityManager ();

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

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

EntityManagerFactory emf = // נאסף מאיפה שהוא EntityManager em = emf.createEntityManager (); // השתמש בו בשרשור הנוכחי

עם זאת, הדברים נעשים אינטואיטיביים נגד בעת שימוש בניהול מיכל EntityManagerס. לדוגמה:

@Service בכיתה ציבורית MovieService {@PersistenceContext // או אפילו @ EntityManager entityManager פרטי; // הושמט }

נראה כי אחד EntityManager יש לשתף מופע לכל הפעולות. עם זאת, המכולה (JakartaEE או Spring) מזריקה פרוקסי מיוחד במקום פשוט EntityManager פה. אביב, למשל, מזריק פרוקסי מסוג SharedEntityManagerCreator.

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

כך או כך, המכולה מבטיחה שכל אחד מהם EntityManager מוגבל לחוט אחד.

5. פעולות ישות במצב שינה

ה EntityManager API מספק אוסף של שיטות. אנו יכולים לתקשר עם מסד הנתונים על ידי שימוש בשיטות אלה.

5.1. ישויות מתמשכות

על מנת שיהיה אובייקט המשויך ל- EntityManager, אנו יכולים לעשות שימוש ב- להתמיד() שיטה :

חלל ציבורי saveMovie () {EntityManager em = getEntityManager (); em.getTransaction (). להתחיל (); סרט סרט = סרט חדש (); movie.setId (1L); movie.setMovieName ("הסנדק"); movie.setReleaseYear (1972); movie.setLanguage ("אנגלית"); em.persist (סרט); em.getTransaction (). commit (); }

ברגע שהאובייקט נשמר במסד הנתונים, הוא נמצא ב- מַתְמִיד מדינה.

5.2. טוען ישויות

לצורך אחזור אובייקט ממסד הנתונים, אנו יכולים להשתמש ב- למצוא() שיטה.

כאן, השיטה מחפשת לפי המפתח הראשי. למעשה, השיטה מצפה לסוג מחלקת הישויות והמפתח הראשי:

סרט ציבורי getMovie (Long movieId) {EntityManager em = getEntityManager (); סרט סרט = em.find (Movie.class, חדש ארוך (movieId)); em.detach (סרט); סרט חזרה; }

עם זאת, אם אנו זקוקים רק להתייחסות לישות, אנו יכולים להשתמש ב- getReference () במקום זאת. למעשה, הוא מחזיר פרוקסי לישות:

סרט movieRef = em.getReference (Movie.class, חדש ארוך (movieId));

5.3. ניתוק ישויות

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

em.detach (סרט);

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

5.4. מיזוג גופים

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

אנחנו יכולים לעשות שימוש ב- לְמַזֵג() שיטה, למצבים כאלה. שיטת המיזוג עוזרת להכניס את השינויים שנעשו לישות המנותקת, בישות המנוהלת, אם בכלל:

חלל ציבורי mergeMovie () {EntityManager em = getEntityManager (); סרט סרט = getMovie (1L); em.detach (סרט); movie.setLanguage ("איטלקית"); em.getTransaction (). להתחיל (); em.merge (סרט); em.getTransaction (). commit (); }

5.5. שאילתות לגופים

יתר על כן, אנו יכולים לעשות שימוש ב- JPQL לשאילתת ישויות. נפעיל getResultList () להוציא אותם להורג.

כמובן, אנו יכולים להשתמש ב- getSingleResult (), אם השאילתה מחזירה רק אובייקט יחיד:

queryForMovies () ציבורי רשימה () {EntityManager em = getEntityManager (); רשימת סרטים = em.createQuery ("בחר סרט מתוך סרט סרט שבו movie.language =? 1"). SetParameter (1, "אנגלית") .getResultList (); להחזיר סרטים; }

5.6. הסרת ישויות

בנוסף, אנו יכולים להסיר ישות ממסד הנתונים באמצעות לְהַסִיר() שיטה. חשוב לציין כי האובייקט אינו מנותק אלא מוסר.

כאן המצב של הישות משתנה ממתמשך לחדש:

חלל ציבורי removeMovie () {EntityManager em = HibernateOperations.getEntityManager (); em.getTransaction (). להתחיל (); סרט סרט = em.find (Movie.class, חדש ארוך (1L)); em.remove (סרט); em.getTransaction (). commit (); }

6. מסקנה

במאמר זה, בחנו את EntityManager ב שינה. בדקנו את הסוגים והתצורה ולמדנו על השיטות השונות הקיימות ב- API לעבודה עם ה- הקשר התמדה.

כמו תמיד, ניתן להשתמש בקוד המשמש במאמר ב- Github.