مساء الخير. أود في هذه المقالة أن أشارككم تجربتي الأولى مع أشياء مثل Maven، وSpring، وHibernate، وMySQL، وTomcat أثناء عملية إنشاء تطبيق CRUD بسيط. هذا هو الجزء الثالث من 4. هذه المقالة مخصصة في المقام الأول لأولئك الذين أكملوا بالفعل مستويات 30-40 هنا، ولكنهم لم يغامروا بعد بما هو أبعد من Java النقي وبدأوا للتو (أو على وشك البدء) في دخول العالم المفتوح مع كل هذه التقنيات والأطر وغيرها من الكلمات غير المألوفة. هذا هو الجزء الثالث من المقالة "مقدمة إلى Maven وSpring وMySQL وHbernate وأول تطبيق CRUD." يمكن مشاهدة الأجزاء السابقة من خلال الروابط التالية:
- مقدمة إلى Maven وSpring وMySQL وHbernate وأول تطبيق CRUD (الجزء الأول)
- مقدمة إلى Maven وSpring وMySQL وHbernate وأول تطبيق CRUD (الجزء 2)
محتوى:
إنشاء وربط قاعدة البيانات
حسنًا، لقد حان الوقت لبدء العمل على قاعدة البيانات. قبل ربط Hibernate والتفكير في كيفية عمل كل شيء هناك، دعونا أولاً نلقي نظرة على قاعدة البيانات نفسها، أي. لنقم بإنشائه وربطه وصنعه وملء العلامة. سوف نستخدم DBMS (نظام إدارة قواعد البيانات) MySQL (بالطبع، يجب عليك أولاً التنزيل والتثبيت). SQL (لغة الاستعلام الهيكلية) هي لغة برمجة تعريفية تستخدم لإنشاء البيانات وتعديلها ومعالجتها في قاعدة بيانات علائقية. في قواعد البيانات هذه، يتم تخزين البيانات في شكل جداول. كيف يتواصل التطبيق مع قاعدة البيانات (نقل استعلامات SQL إلى قاعدة البيانات وإرجاع النتائج). لهذا، لدى Java شيء مثل JDBC (Java DataBase Connectivity) ، والذي، ببساطة، عبارة عن مجموعة من الواجهات والفئات للعمل مع قواعد البيانات. للتفاعل مع قاعدة البيانات، تحتاج إلى إنشاء اتصال؛ ولهذا الغرض، تحتوي الحزمةjava.sql
على فئة Connection
. هناك عدة طرق لإنشاء اتصال، على سبيل المثال يمكنك استخدام طريقة getConnection
الفصل DriverManager
. ومع ذلك، لا يتم التفاعل مع قاعدة البيانات مباشرة، لأن هناك العديد من قواعد البيانات، وهي مختلفة. لذلك يوجد لكل منهم برنامج تشغيل JDBC خاص به، وباستخدام برنامج التشغيل هذا يتم إنشاء اتصال بقاعدة البيانات. لذلك، أولاً وقبل كل شيء، حتى لا يتشتت انتباهنا لاحقًا، فلنقم بتثبيت برنامج تشغيل MySQL . دعونا نضيف pom.xml
التبعية التالية:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
الآن لنقم بإنشاء قاعدة البيانات. عرض -> أداة Windows -> قاعدة البيانات - سيتم فتح لوحة قاعدة البيانات. جديد (أخضر +) -> مصدر البيانات -> MySQL - سيتم فتح نافذة تحتاج فيها إلى تحديد اسم المستخدم وكلمة المرور، وقمنا بتعيينهما عند تثبيت MySQL (على سبيل المثال، استخدمت الجذر والجذر). المنفذ (الافتراضي لـ MySQL 3306)، الاسم، وما إلى ذلك. اتركها كما هي. يمكنك اختبار الاتصال باستخدام زر " اختبار الاتصال ". انقر فوق "موافق" والآن نحن متصلون بخادم MySQL. بعد ذلك، لنقم بإنشاء قاعدة بيانات. للقيام بذلك، يمكنك كتابة برنامج نصي في وحدة التحكم التي تفتح:
CREATE DATABASE test
انقر فوق تنفيذ وقاعدة البيانات جاهزة، الآن يمكنك توصيلها، للقيام بذلك، ارجع إلى خصائص مصدر البيانات وأدخل اسم قاعدة البيانات (اختبار) في حقل قاعدة البيانات، ثم أدخل اسم المستخدم وكلمة المرور مرة أخرى وانقر فوق موافق. الآن نحن بحاجة إلى عمل جدول. يمكنك استخدام الأدوات الرسومية، ولكن للمرة الأولى، ربما يكون من المفيد كتابة نص يدويًا لترى كيف يبدو:
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
مهمته بشكل أساسي، يمكنك حذفها.
أورم وJPA
بطريقة جيدة، ومن أجل فهم أفضل، من الأفضل البدء في التعرف على قواعد البيانات بالترتيب، من البداية، دون أي سبات وأشياء أخرى. لذلك، سيكون من الجيد العثور على بعض الأدلة ومحاولة العمل مع فئات JDBC أولاً، وكتابة استعلامات SQL يدويًا، وما إلى ذلك. حسنًا، دعنا ننتقل إلى نموذج ORM على الفور. ماذا يعني هذا؟ بالطبع، من المستحسن مرة أخرى أن تقرأ عن هذا بشكل منفصل، لكنني سأحاول وصفه بإيجاز. ORM (رسم الخرائط العلائقية للكائنات أو رسم الخرائط العلائقية للكائنات) هي تقنية لتعيين الكائنات في هياكل قواعد البيانات العلائقية، أي. لتمثيل كائن Java الخاص بنا كصف جدول. بفضل ORM، لا داعي للقلق بشأن كتابة نصوص SQL والتركيز على العمل مع الكائنات. كيفية استخدامها. لدى Java شيء رائع آخر، JPA (Java Persistence API)، الذي يطبق مفهوم ORM. JPA هي مثل هذه المواصفات، فهي تصف متطلبات الكائنات، وتحدد واجهات مختلفة وشروحًا للعمل مع قاعدة البيانات. JPA هو في الأساس وصف ومعيار. لذلك، هناك العديد من التطبيقات المحددة، أحدها (وأحد أكثرها شيوعًا) هو السبات، وهو جوهر هذا الإطار. السبات هو تطبيق لمواصفات 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 عادية ، مع حقول خاصة وحروف ومحددات لها. يجب أن يحتوي على مُنشئ غير خاص بدون معلمات (أو مُنشئ افتراضي)، ويجب أن يحتوي على مفتاح أساسي، أي. شيء من شأنه أن يحدد بشكل فريد كل سجل من هذه الفئة في قاعدة البيانات. يمكنك أيضًا أن تقرأ عن جميع متطلبات هذه الفئة بشكل منفصل. لنجعل صفنا 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 عن القيمة السابقة.
خصائص السبات
حسنًا، لنبدأ في إعداد وضع السبات الخاص بنا. وقبل كل شيء، دعونا نضع بعض المعلومات، مثل اسم المستخدم وكلمة المرور وعنوان 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
حسنًا، كل شيء واضح من الأعلى، معلمات الاتصال بقاعدة البيانات، أي. اسم فئة برنامج التشغيل وعنوان url واسم المستخدم وكلمة المرور. hibernate.dialect
- هذه الخاصية مطلوبة للإشارة إلى الإصدار المعين من لغة SQL المستخدم للإسبات. الحقيقة هي أنه في كل نظام إدارة قواعد بيانات (DBMS)، من أجل توسيع القدرات أو إضافة بعض الوظائف أو تحسين شيء ما، عادةً ما يقومون بتحديث اللغة قليلاً. ونتيجة لذلك، اتضح أن كل نظام إدارة قواعد البيانات لديه لهجة SQL الخاصة به. كما هو الحال مع اللغة الإنجليزية، يبدو أن اللغة هي نفسها، ولكن في أستراليا أو الولايات المتحدة الأمريكية أو بريطانيا ستكون مختلفة قليلاً، وقد يكون لبعض الكلمات معاني مختلفة. ومن أجل تجنب أي مشاكل في الفهم، عليك أن تخبر Hibernate مباشرة بما يجب عليه التعامل معه بالضبط. hibernate.show_sql
— بفضل هذه الخاصية، سيتم عرض الاستعلامات الخاصة بقاعدة البيانات في وحدة التحكم. هذا ليس ضروريا، ولكن مع هذا الشيء يمكنك على الأقل إلقاء نظرة على ما يحدث، وإلا فقد يبدو أن السبات يفعل نوعا من السحر. حسنًا، بالطبع، لن يكون عرضه واضحًا تمامًا، فمن الأفضل استخدام نوع من المسجل لهذا الغرض، ولكن هذا شيء لوقت آخر، في الوقت الحالي سيفي بالغرض.
تكوين السبات
دعنا ننتقل إلى إعداد التكوين.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
لإدارة المعاملات. يعمل السبات مع قاعدة البيانات باستخدام المعاملات، فهي ضرورية لتنفيذ مجموعة معينة من العمليات ككل واحد، أي. إذا كانت الطريقة بها مشاكل في أي عملية واحدة، فلن يتم تنفيذ جميع العمليات الأخرى، بحيث لا يحدث الأمر كما في المثال الكلاسيكي لتحويل الأموال، عند اكتمال عملية سحب الأموال من حساب واحد، ولكن لم تنجح عملية الكتابة للآخر، ونتيجة لذلك اختفت الأموال.@PropertySource
- ربط ملف الخصائص الذي قمنا بإنشائه مؤخرًا.Environment
- من أجل الحصول على خصائص منproperty
ملف.hibernateProperties
- هذه الطريقة مطلوبة لتمثيل خصائص السبات ككائن خصائصDataSource
- يستخدم لإنشاء اتصال بقاعدة البيانات. يعد هذا بديلاً لبرنامج DriverManager ، الذي استخدمناه سابقًا عندما أنشأنا ملفmain
. تقول الوثائق أنهDataSource
من الأفضل استخدامها. وهذا ما سنفعله بالطبع، دون أن ننسى أن نقرأ على الإنترنت ما هو الفرق والمزايا. إحدى الفوائد على وجه الخصوص هي القدرة على إنشاء تجمع اتصال قاعدة البيانات (DBCP).sessionFactory
- لإنشاء جلسات يتم من خلالها تنفيذ العمليات مع كائنات الكيان. نقوم هنا بتعيين مصدر البيانات وخصائص السبات وفي أي حزمة نحتاج إلى البحث عن فئات الكيانات.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();
}
هناك نقطتان هنا. أولاً، تم عرض تحذير. ويرجع ذلك إلى حقيقة أننا نريد تلقي معلمات List<Film>
، لكن الطريقة ترجع ببساطة List
لأنه في وقت الترجمة لا يُعرف نوع الطلب الذي سيرجعه. لذا فإن الفكرة تحذرنا من أننا نقوم بعملية تحويل غير آمنة، مما قد يؤدي إلى مشاكل. هناك عدة طرق صحيحة للقيام بذلك حتى لا يطرح مثل هذا السؤال. يمكنك البحث عن المعلومات على شبكة الإنترنت. ولكن دعونا لا نهتم بهذا الآن. الحقيقة هي أننا نعرف بالضبط ما هو النوع الذي سيتم إرجاعه، لذلك لن تنشأ أي مشاكل هنا، يمكنك ببساطة تجاهل التحذير. ولكن، حتى لا تكون عيناك قبيحة، يمكنك تعليق تعليق توضيحي فوق الطريقة @SupressWarning("unchecked")
. من خلال القيام بذلك، نخبر المترجم نوعًا ما، شكرًا لك، يا صديقي، على اهتمامك، لكنني أعرف ما أفعله وأتحكم في كل شيء، حتى تتمكن من الاسترخاء ولا تقلق بشأن هذه الطريقة. ثانياً، تم وضع خط تحت الفكرة باللون الأحمر " from Film
". إنه مجرد استعلام HQL (لغة استعلام السبات) ولا تفهم الفكرة ما إذا كان كل شيء صحيحًا أم أن هناك خطأ. يمكنك الانتقال إلى إعدادات الفكرة وضبط كل شيء يدويًا (ابحث على الإنترنت إذا كنت مهتمًا). أو يمكنك ببساطة إضافة دعم لإطار عمل Hibernate، للقيام بذلك، انقر بزر الماوس الأيمن على المشروع، وحدد Add Framework Support ، وحدد مربع Hibernate ثم انقر فوق OK. بعد ذلك، على الأرجح في فئة الكيان ( Film
) سيتم أيضًا وضع خط تحت الكثير من الأشياء باللون الأحمر، على سبيل المثال، حيث @Table(name = "films")
سيصدر التعليق التوضيحي تحذيرًا لا يمكن حل جدول 'films' . مرة أخرى، لا يوجد شيء خاطئ هنا، هذا ليس خطأ في التصميم، كل شيء سيتم تجميعه وعمله. تم التأكيد على الفكرة لأنها لا تعرف شيئًا عن قاعدتنا. لإصلاح ذلك، دعونا ندمج الفكرة مع قاعدة البيانات. عرض -> أداة Windows -> الثبات (سيتم فتح علامة تبويب) -> زر الفأرة الأيمن، وحدد تعيين مصادر البيانات -> في مصدر البيانات، وحدد الاتصال بقاعدة البيانات وانقر فوق موافق . عندما تم إصلاح كل هذا، كان لا يزال هناك شيء متبقي. دعنا نذهب إلى مستوى أعلى، إلى الخدمة. في الفصل، FilmServiceImpl
نحتفل allFilms
بطريقة الربيع بتعليق توضيحي @Transactional
، والذي سيشير إلى أنه يجب تنفيذ الطريقة في المعاملة (بدون ذلك، سيرفض السبات العمل):
@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 وHbernate وأول تطبيق CRUD (الجزء 4)
GO TO FULL VERSION