אחר הצהריים טובים. במאמר זה אני רוצה לשתף את המפגש הראשון שלי עם דברים כמו Maven, Spring, Hibernate, MySQL ו- Tomcat בתהליך של יצירת יישום CRUD פשוט. זהו החלק השלישי מתוך 4. המאמר מיועד בעיקר לאלו שכבר השלימו כאן 30-40 רמות, אך עדיין לא יצאו אל מעבר לג'אווה הטהורה ורק מתחילים (או עומדים להתחיל) להיכנס לעולם הפתוח עם כל הטכנולוגיות, המסגרות ושאר המילים הלא מוכרות הללו. זהו החלק השלישי של המאמר "מבוא ל-Maven, Spring, MySQL, Hibernate ויישום ה-CRUD הראשון". ניתן לראות את החלקים הקודמים בקישורים:
- היכרות עם Maven, Spring, MySQL, Hibernate ויישום ה-CRUD הראשון (חלק 1)
- היכרות עם Maven, Spring, MySQL, Hibernate ויישום ה-CRUD הראשון (חלק 2)
תוֹכֶן:
יצירה וחיבור של מסד נתונים
ובכן, הגיע הזמן להתחיל לעבוד על מסד הנתונים. לפני חיבור Hibernate ונחשוב על איך הכל צריך לעבוד שם, ראשית בואו נסתכל על מסד הנתונים עצמו, כלומר. בואו ניצור אותו, נחבר אותו, נכין אותו ונמלא את השלט. אנו נשתמש ב-DBMS (מערכת ניהול מסד נתונים) MySQL (כמובן, תחילה עליך להוריד ולהתקין). SQL (שפת שאילתות מובנית) היא שפת תכנות הצהרתית המשמשת ליצירה, שינוי ולטפל בנתונים במסד נתונים יחסי. במסדי נתונים כאלה, הנתונים מאוחסנים בצורה של טבלאות. כיצד האפליקציה מתקשרת עם בסיס הנתונים (משדר שאילתות SQL לבסיס הנתונים ומחזיר תוצאות). בשביל זה, ל-Java יש דבר כזה כמו JDBC (קישוריות לבסיס נתונים של Java) , שהוא, במילים פשוטות, קבוצה של ממשקים ומחלקות לעבודה עם מסדי נתונים. כדי ליצור אינטראקציה עם מסד הנתונים, עליך ליצור חיבור; לשם כך, לחבילהjava.sql
יש מחלקה Connection
. ישנן מספר דרכים ליצור חיבור, למשל אתה יכול להשתמש בשיטת getConnection
המחלקה DriverManager
. עם זאת, האינטראקציה עם מסד הנתונים אינה מתבצעת ישירות, מכיוון שישנם מסדי נתונים רבים, והם שונים. אז לכל אחד מהם יש JDBC דרייבר משלו, באמצעות דרייבר זה נוצר חיבור למסד הנתונים. לכן, קודם כל, כדי לא להסיח את דעתו מכך מאוחר יותר, בואו נתקין את מנהל ההתקן של MySQL . בואו נוסיף את pom.xml
התלות הבאה:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
עכשיו בואו ניצור את מסד הנתונים. תצוגה -> חלונות כלי -> מסד נתונים - חלונית מסד הנתונים תיפתח. חדש (ירוק +) -> מקור נתונים -> MySQL - ייפתח חלון בו צריך לציין את שם המשתמש והסיסמה, הגדרנו אותם בעת התקנת MySQL (לדוגמה, השתמשתי ב-root וב-root). יציאה (ברירת מחדל עבור MySQL 3306), שם וכו'. להשאיר את זה כמו שהוא. אתה יכול לבדוק את החיבור באמצעות כפתור " בדוק חיבור ". לחץ על אישור ועכשיו אנחנו מחוברים לשרת MySQL. לאחר מכן, בואו ניצור מסד נתונים. לשם כך, אתה יכול לכתוב סקריפט במסוף שנפתח:
CREATE DATABASE test
יש ללחוץ על ביצוע ומסד הנתונים מוכן, כעת ניתן לחבר אותו לשם כך חזרו ל-Data Source Properties והזן את שם מסד הנתונים (בדיקה) בשדה Database ולאחר מכן הזינו שוב את שם המשתמש והסיסמה ולחצו על OK. עכשיו אנחנו צריכים להכין שולחן. אתה יכול להשתמש בכלים גרפיים, אבל בפעם הראשונה, כנראה שכדאי לכתוב סקריפט ביד כדי לראות איך הוא נראה:
USE test;
CREATE TABLE films
(
id int(10) PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(100) NOT NULL,
year int(4),
genre VARCHAR(20),
watched BIT DEFAULT false NOT NULL
)
COLLATE='utf8_general_ci';
CREATE UNIQUE INDEX films_title_uindex ON films (title);
INSERT INTO `films` (`title`,`year`,`genre`, watched)
VALUES
("Inception", 2010, "sci-fi", 1),
("The Lord of the Rings: The Fellowship of the Ring", 2001, "fantasy", 1),
("Tag", 2018, "comedy", 0),
("Gunfight at the O.K. Corral", 1957, "western", 0),
("Die Hard", 1988, "action", 1);
נוצרת טבלה עם השם films
עם עמודות וכו' id
. title
עבור כל עמודה מצוין הסוג (גודל פלט מרבי בסוגריים).
PRIMARY KEY
- זהו המפתח הראשי, המשמש לזיהוי ייחודי של רשומה בטבלה (מה שמרמז על ייחודיות)AUTO_INCREMENT
- הערך ייווצר אוטומטית (כמובן שהוא לא יהיה אפס, אז אתה לא צריך לציין זאת)NOT NULL
- כאן הכל גם ברור, הוא לא יכול להיות ריקDEFAULT
— הגדר את ערך ברירת המחדלCOLLATE
- קידודCREATE UNIQUE INDEX
- להפוך את התחום לייחודיINSERT INTO
- הוסף רשומה לטבלה
main
באופן זמני. באופן עקרוני, אתה יכול לשים אותו בכל מקום, אפילו במחלקת הבקר, אפילו בדגם או בתצורה, זה לא משנה, אתה רק צריך להשתמש בו כדי לוודא שהכל בסדר עם החיבור ואפשר למחוק אותו. אבל כדי להיות זהירים יותר, בואו ניצור עבורו מחלקה נפרדת Main
:
package testgroup.filmography;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/test";
String username = "root";
String password = "root";
System.out.println("Connecting...");
try (Connection connection = DriverManager.getConnection(url, username, password)) {
System.out.println("Connection successful!");
} catch (SQLException e) {
System.out.println("Connection failed!");
e.printStackTrace();
}
}
}
הכל פשוט כאן, אנחנו מגדירים את פרמטרי החיבור למסד הנתונים שלנו ומנסים ליצור חיבור. בואו נשיק את זה main
ונסתכל. אז, קיבלתי חריגה, כמה בעיות באזור זמן, ואזהרה אחרת לגבי SSL. לאחר גלישה באינטרנט, ניתן לגלות שמדובר בבעיה נפוצה למדי, וכאשר משתמשים בגרסאות שונות של הדרייבר (mysql-connector-java), היא יכולה לקלל אחרת. לדוגמה, גיליתי בניסוי שבשימוש בגרסה 5.1.47 אין חריגים בגלל אזור הזמן, החיבור נוצר כרגיל, אבל אזהרת SSL עדיין צצה. עם כמה גרסאות אחרות נראה היה שיש חריג לגבי SSL, ולא רק אזהרה. אוקיי, זו לא הנקודה. אתה יכול לנסות לטפל בנושא הזה בנפרד, אבל לא ניכנס לזה עכשיו. הפתרון לכל זה די פשוט, אתה צריך לציין פרמטרים נוספים ב- url , כלומר serverTimezone
, אם הבעיה היא באזור הזמן, ואם useSSL
הבעיה היא עם SSL:
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=Europe/Minsk&useSSL=false";
כעת קבענו את אזור הזמן והשבתנו את ה-SSL. אנחנו משיקים אותו שוב main
והוואי - החיבור הצליח! טוב, נהדר, הבנו איך ליצור חיבור. הכיתה Main
בעצם השלימה את המשימה שלה, אתה יכול למחוק אותה.
ORM ו-JPA
בצורה טובה, להבנה טובה יותר, עדיף להתחיל להכיר את מאגרי המידע לפי הסדר, כבר מההתחלה, ללא כל תרדמה ודברים אחרים. לכן, זה יהיה רעיון טוב למצוא כמה מדריכים ולנסות תחילה לעבוד עם מחלקות JDBC, לכתוב שאילתות SQL באופן ידני וכן הלאה. ובכן, בואו נעבור למודל ה- ORM מיד. מה זה אומר? כמובן ששוב מומלץ לקרוא על כך בנפרד, אך אנסה לתאר זאת בקצרה. ORM (Object-Relational Mapping או Object-Relational Mapping) היא טכנולוגיה למיפוי אובייקטים לתוך מבני מסד נתונים יחסיים, כלומר. לייצג את אובייקט Java שלנו כשורה בטבלה. הודות ל-ORM, אינך צריך לדאוג לכתיבת סקריפטים של SQL ולהתמקד בעבודה עם אובייקטים. איך להשתמש בזה. לג'אווה יש דבר נהדר נוסף, JPA (Java Persistence API), שמיישם את תפיסת ה-ORM. JPA הוא מפרט כזה, הוא מתאר את הדרישות לאובייקטים, הוא מגדיר ממשקים והערות שונות לעבודה עם מסד הנתונים. JPA הוא בעצם תיאור, תקן. לכן, יש הרבה יישומים ספציפיים, שאחד מהם (ואחד הפופולריים) הוא Hibernate, שהוא המהות של המסגרת הזו. Hibernate הוא יישום של מפרט JPA שנועד לפתור בעיות של מיפוי יחסי אובייקט (ORM). אנחנו צריכים לחבר את כל העניין הזה לפרויקט שלנו. בנוסף, כדי שהאביב שלנו לא יעמוד מהצד וגם ישתתף בכל התנועה הזו עם מאגרי מידע, אנחנו צריכים לחבר עוד כמה מודולים, כי כל מה שקיבלנו מהתלות של spring-webmvc כבר לא מספיק בשביל זה. נזדקק גם ל- spring-jdbc כדי לעבוד עם מסד הנתונים, ל-spring-tx כדי לתמוך בעסקאות, ו- spring-orm לעבודה עם Hibernate. בואו נוסיף תלות לpom.xml
:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.7.Final</version>
</dependency>
די בשתי התלות הללו. javax.persistence-api
יגיע יחד עם hibernate-core , ו- spring-jdbc ו- spring-tx יחד עם spring-orm .
יֵשׁוּת
אז אנחנו רוצים שאובייקטי מחלקה יוכלוFilm
להיות מאוחסנים במסד הנתונים. לשם כך, על הכיתה לעמוד במספר תנאים. ב-JPA יש דבר כזה ישות בשביל זה . כיתת ישות היא כיתת POJO רגילה , עם שדות פרטיים ו-getters ו-seters עבורם. חייב להיות בו בנאי לא פרטי ללא פרמטרים (או בנאי ברירת מחדל), והוא חייב להיות בעל מפתח ראשי, כלומר. משהו שיזהה באופן ייחודי כל רשומה של מחלקה זו במסד הנתונים. ניתן גם לקרוא על כל הדרישות לשיעור כזה בנפרד. בואו נהפוך את הכיתה שלנו Film
לישות באמצעות הערות JPA:
package testgroup.filmography.model;
import javax.persistence.*;
@Entity
@Table(name = "films")
public class Film {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "title")
private String title;
@Column(name = "year")
private int year;
@Column(name = "genre")
private String genre;
@Column(name = "watched")
private boolean watched;
// + getters and setters
}
@Entity
- מציין כי מחלקה זו היא ישות.@Table
- מצביע על טבלה ספציפית כדי להציג ישות זו.@Id
- מציין ששדה זה הוא מפתח ראשי, כלומר. מאפיין זה ישמש לזיהוי כל ערך ייחודי.@Column
- מחבר שדה לעמודת טבלה. אם שמות העמודות של השדות והטבלה זהים, ניתן להשמיט אותם.@GeneratedValue
- המאפיין ייווצר באופן אוטומטי; בסוגריים תוכל לציין כיצד. לא נבין עכשיו איך בדיוק עובדות אסטרטגיות שונות. מספיק לדעת שבמקרה זה כל ערך חדש יגדל ב-1 מהקודם.
מאפייני שינה
ובכן, בואו נתחיל להגדיר את מצב Hibernate שלנו. וקודם כל, בואו נכניס קצת מידע, כמו שם משתמש וסיסמה, כתובת URL ועוד משהו בקובץ נפרד. אפשר כמובן לציין אותם כשורה רגילה ישירות בכיתה, כפי שעשינו כשבדקנו את החיבור (String username = "root";
ואחר כך העברנו אותו למתודה ליצירת החיבור). אבל עדיין נכון יותר לאחסן נתונים סטטיים כאלה בקובץ כלשהו property
. ואם, למשל, אתה צריך לשנות את מסד הנתונים, אז לא תצטרך לעבור על כל המחלקות ולחפש היכן הוא משמש; זה יספיק לשנות את הערך בקובץ הזה פעם אחת. בואו ניצור קובץ db.properties בספריית המשאבים :
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=Europe/Minsk&useSSL=false
jdbc.username=root
jdbc.password=root
hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
hibernate.show_sql=true
ובכן, הכל ברור מלמעלה, פרמטרים לחיבור למסד הנתונים, כלומר. שם מחלקה לנהג, כתובת אתר, שם משתמש וסיסמה. hibernate.dialect
- מאפיין זה נחוץ כדי לציין למצב Hibernate באיזו גרסה מסוימת של שפת SQL נעשה שימוש. העובדה היא שבכל DBMS, כדי להרחיב את היכולות, להוסיף פונקציונליות כלשהי או לייעל משהו, הם בדרך כלל משדרגים מעט את השפה. כתוצאה מכך, מתברר שלכל DBMS יש ניב SQL משלו. זה כמו באנגלית, נראה שהשפה זהה, אבל באוסטרליה, ארה"ב או בריטניה זה יהיה מעט שונה, ולכמה מילים עשויות להיות משמעויות שונות. וכדי למנוע בעיות בהבנה, אתה צריך לומר ישירות ל-Hibernate עם מה בדיוק הוא צריך להתמודד. hibernate.show_sql
- הודות למאפיין זה, שאילתות למסד הנתונים יוצגו במסוף. זה לא הכרחי, אבל עם הדבר הזה אתה יכול לפחות להסתכל על מה שקורה, אחרת אולי נראה כי Hibernate עושה סוג של קסם. ובכן, כמובן, זה לא יהיה ברור לגמרי לתצוגה; עדיף להשתמש בסוג של לוגר בשביל זה, אבל זה משהו לפעם אחרת, לעת עתה זה יצליח.
תצורת שינה
בואו נעבור להגדרת התצורה.config
בואו ניצור מחלקה בחבילה HibernateConfig
:
package testgroup.filmography.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@ComponentScan(basePackages = " testgroup.filmography")
@EnableTransactionManagement
@PropertySource(value = "classpath:db.properties")
public class HibernateConfig {
private Environment environment;
@Autowired
public void setEnvironment(Environment environment) {
this.environment = environment;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
return properties;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("testgroup.filmography.model");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
}
יש כאן די הרבה דברים חדשים, אז עדיף לחפש בנוסף מידע על כל פריט במקורות שונים. בוא נעבור על זה בקצרה כאן.
@Configuration
כבר הבנו@ComponentScan
מתי עשינו את השיעורWebConfig
.@EnableTransactionManagement
- מאפשר לך להשתמש בוTransactionManager
לניהול עסקאות. Hibernate עובד עם מסד הנתונים באמצעות טרנזקציות; הן נחוצות כדי שמערכת מסוימת של פעולות תתבצע כמכלול אחד, כלומר. אם לשיטה יש בעיות בכל פעולה אחת, אז כל האחרות לא יבוצעו, כך שזה לא יקרה כמו בדוגמה הקלאסית עם העברת כסף, כאשר הפעולה של משיכת כסף מחשבון אחד הושלמה, אלא פעולת הכתיבה לאחר לא עבדה, וכתוצאה מכך הכסף נעלם.@PropertySource
- חיבור קובץ המאפיינים שיצרנו לאחרונה.Environment
- על מנת לקבל מאפייניםproperty
מקובץ.hibernateProperties
- שיטה זו נחוצה כדי לייצג מאפייני Hibernate כאובייקט PropertiesDataSource
- משמש ליצירת חיבור למסד הנתונים. זוהי חלופה ל- DriverManager , שבה השתמשנו קודם לכן כאשר יצרנו את ה-main
. התיעוד אומר שעדיףDataSource
להשתמש בו. זה מה שנעשה, כמובן, לא נשכח לקרוא באינטרנט מה ההבדל והיתרונות. יתרון אחד במיוחד הוא היכולת ליצור מאגר חיבורי מסד נתונים (DBCP).sessionFactory
- ליצור מפגשים שבעזרתם מתבצעות פעולות עם אובייקטים של ישות. כאן אנו מגדירים את מקור הנתונים, מאפייני Hibernate ובאיזה חבילה עלינו לחפש מחלקות ישויות.transactionManager
- כדי להגדיר את מנהל העסקאות.
DataSource
. התיעוד אומר כי השימוש ביישום הסטנדרטי, כלומר DriverManagerDataSource
, אינו מומלץ, מכיוון זה רק תחליף לאיסוף חיבור רגיל ובדרך כלל מתאים רק לבדיקות וכדומה. עבור יישום רגיל, עדיף להשתמש בספריית DBCP כלשהי. ובכן, עבור היישום שלנו, כמובן, מה שיש לנו מספיק, אבל כדי להשלים את התמונה, אולי עדיין נשתמש ביישום אחר כפי שהומלץ. בואו נוסיף את pom.xml
התלות הבאה:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>9.0.10</version>
</dependency>
ובשיטת dataSource
המחלקה HibernateConfig
אנו מחליפים אותו DriverManagerDataSource
באחד BasicDataSource
מהחבילה org.apache.tomcat.dbcp.dbcp2
:
BasicDataSource dataSource = new BasicDataSource();
ובכן, נראה שהכל מוכן, התצורה מוכנה, כל מה שנותר הוא להוסיף אותה ל- AppInitializer שלנו :
protected Class<?>[] getRootConfigClasses() {
return new Class[]{HibernateConfig.class};
}
שכבת גישה לנתונים
הגיע הזמן סוף סוף להתחיל עם ה-DAO שלנו. אנחנו הולכים לכיתהFilmDAOImpl
וקודם כל אנחנו מוחקים משם את רשימת הניסיון, אנחנו כבר לא צריכים אותה. בואו נוסיף מפעל הפעלה ונעבוד דרכו.
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
מלכתחילה ניצור שיטה להצגת עמוד עם רשימת סרטים, בו נקבל סשן ונגיש בקשה למאגר (שליפת כל הרשומות ויצירת רשימה):
public List<Film> allFilms() {
Session session = sessionFactory.getCurrentSession();
return session.createQuery("from Film").list();
}
יש כאן 2 נקודות. ראשית, הוצגה אזהרה. זה נובע מהעובדה שאנו רוצים לקבל פרמטרized List<Film>
, אבל השיטה חוזרת פשוט List
כי בזמן הקומפילציה לא ידוע איזה סוג הבקשה תחזיר. אז הרעיון מזהיר אותנו שאנחנו עושים המרה לא בטוחה, שעלולה לגרום לצרות. יש עוד כמה דרכים נכונות לעשות זאת כדי ששאלה כזו לא תתעורר. אתה יכול לחפש מידע באינטרנט. אבל בואו לא נתעסק בזה עכשיו. העובדה היא שאנו יודעים בדיוק איזה סוג יוחזר, כך שלא יתעוררו כאן בעיות, אתה יכול פשוט להתעלם מהאזהרה. אבל, כדי שהעיניים שלך לא יהיו כאבי עיניים, אתה יכול לתלות הערה מעל השיטה @SupressWarning("unchecked")
. על ידי כך, אנחנו סוג של אומר למהדר, תודה לך, חבר, על הדאגה שלך, אבל אני יודע מה אני עושה ויש לי הכל בשליטה, אז אתה יכול להירגע ולא לדאוג לגבי השיטה הזו. שנית, הרעיון מסומן בקו תחתון באדום " from Film
". זו רק שאילתת HQL (Hibernate Query Language) והרעיון לא מבין אם הכל נכון או שיש שגיאה. אתה יכול להיכנס להגדרות הרעיון ולהתאים הכל ידנית (חפש באינטרנט אם אתה מעוניין). או שאתה יכול פשוט להוסיף תמיכה עבור המסגרת Hibernate, כדי לעשות זאת, לחץ לחיצה ימנית על הפרויקט, בחר הוסף תמיכה מסגרת , סמן את התיבה עבור Hibernate ולחץ על אישור. לאחר מכן, סביר להניח שבמחלקת הישות ( Film
) הרבה דברים יודגשו גם באדום, למשל, שם ההערה @Table(name = "films")
תוציא את האזהרה Cannot resolve table 'films' . שוב, אין כאן שום דבר רע, זו לא טעות עיצוב, הכל יקמפל ויעבוד. הרעיון מודגש כי הוא לא יודע דבר על הבסיס שלנו. כדי לתקן זאת, בואו נשלב את הרעיון עם מסד הנתונים. View -> Tool Windows -> Persistense (תיפתח כרטיסייה) -> לחצן ימני בעכבר, בחר Assign Data Sources -> ב-Data Source, ציין את החיבור למסד הנתונים ולחץ על OK . כשכל זה תוקן, עדיין נשאר משהו. בואו נלך לרמה גבוהה יותר, לשירות. במחלקה FilmServiceImpl
אנו מסמנים את allFilms
שיטת האביב בהערה @Transactional
, שתציין שיש לבצע את השיטה בעסקה (ללא זאת, Hibernate יסרב לעבוד):
@Transactional
public List<Film> allFilms() {
return filmDAO.allFilms();
}
אז הכל מוכן כאן, אתה לא צריך לגעת בכלום בבקר. ובכן, נראה שרגע האמת הגיע, לחץ על הפעלה ותראה מה קורה. והנה, השלט שלנו, והפעם הוא התקבל לא מרשימה שהכנו בעצמנו ממש בכיתה, אלא ממאגר מידע. מעולה, נראה שהכל עובד. כעת אנו מבצעים את כל שאר פעולות ה-CRUD באותו אופן באמצעות שיטות הפעלה. המחלקה שהתקבלה נראית כך:
package testgroup.filmography.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import testgroup.filmography.model.Film;
import java.util.List;
@Repository
public class FilmDAOImpl implements FilmDAO {
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
@SuppressWarnings("unchecked")
public List<Film> allFilms() {
Session session = sessionFactory.getCurrentSession();
return session.createQuery("from Film").list();
}
@Override
public void add(Film film) {
Session session = sessionFactory.getCurrentSession();
session.persist(film);
}
@Override
public void delete(Film film) {
Session session = sessionFactory.getCurrentSession();
session.delete(film);
}
@Override
public void edit(Film film) {
Session session = sessionFactory.getCurrentSession();
session.update(film);
}
@Override
public Film getById(int id) {
Session session = sessionFactory.getCurrentSession();
return session.get(Film.class, id);
}
}
עכשיו כל מה שנותר הוא לא לשכוח ללכת לשירות ולהוסיף הערה לשיטות @Transactional
. זהו, מוכן. עכשיו אתה יכול לרוץ ולבדוק. לחץ על קישורים וכפתורים, נסה להוסיף/למחוק/לערוך ערכים. אם הכל נעשה כמו שצריך זה אמור לעבוד. כעת זהו יישום CRUD מן המניין המשתמש ב-Hibernate, Spring, MySQL. להמשך... היכרות עם Maven, Spring, MySQL, Hibernate ויישום ה-CRUD הראשון (חלק 1) היכרות עם Maven, Spring, MySQL, Hibernate ויישום CRUD הראשון (חלק 2) היכרות עם Maven, Spring, MySQL, Hibernate וה- יישום ה-CRUD הראשון (חלק 3) מבוא ל-Maven, Spring, MySQL, Hibernate ויישום ה-CRUD הראשון (חלק 4)
GO TO FULL VERSION