در این مقاله با یکی از محبوب ترین فریم ورک های سازمانی برای جاوا آشنا می شوید و اولین اپلیکیشن Hibernate خود را ایجاد می کنید. تا به حال نام Hibernate را نشنیده اید؟ یا شاید نام آن را شنیده اید، اما از آن استفاده نکرده اید؟ یا شاید سعی کردید از آن استفاده کنید، اما موفق نشدید؟ در هر سه مورد - به زیر برش خوش آمدید :)
سلام، همه! در این مقاله، در مورد ویژگی های اصلی فریم ورک Hibernate صحبت می کنم و به شما کمک می کنم اولین برنامه کوچک خود را بنویسید. برای این ما نیاز داریم:
همانطور که می بینید، هیچ چیز پیچیده ای نیست. 6 کلاس + 1 فایل با تنظیمات. ابتدا یک پروژه Maven جدید در IntelliJ IDEA ایجاد کنید. فایل -> پروژه جدید. Maven را از بین انواع پروژه های پیشنهادی انتخاب کنید و به مرحله بعد بروید.
Apache Maven چارچوبی برای ساخت خودکار پروژه ها بر اساس توضیح ساختار آنها در فایل های POM است. کل ساختار پروژه شما در pom.xml توضیح داده می شود، فایلی که خود IDEA در ریشه پروژه شما ایجاد می کند. در تنظیمات پروژه، باید تنظیمات Maven زیر را مشخص کنید: groupId و artifactId. در پروژه ها، groupId معمولاً شرحی از شرکت یا واحد تجاری است. نام دامنه شرکت یا وب سایت می تواند اینجا باشد. به نوبه خود، artifactId نام پروژه است. برای groupdId، می توانید وارد کنید
در آخرین صفحه، به سادگی داده های وارد شده قبلی را تأیید کنید.
بنابراین، ما پروژه را ایجاد کردیم. حالا تنها کاری که باید انجام شود این است که مقداری کد بنویسیم و آن را کار کنیم :) اول از همه: اگر بخواهیم برنامه ای بسازیم که با دیتابیس کار کند، قطعا بدون دیتابیس نمی توانیم کار کنیم! PostgreSQL را از اینجا
دانلود کنید (من از نسخه 9 استفاده می کنم). PostgreSQL دارای یک کاربر پیشفرض 'postgres' است - هنگام نصب باید یک رمز عبور برای آن در نظر بگیرید. رمز عبور را فراموش نکنید. ما بعداً به آن نیاز خواهیم داشت! (به طور کلی، استفاده از پایگاه داده پیشفرض در برنامهها عمل بدی است، اما ما این کار را انجام میدهیم تا با ایجاد پایگاه داده خود، تعداد علل زخمها را کاهش دهیم). اگر با خط فرمان و پرس و جوهای SQL دوست نیستید، خبر خوبی وجود دارد. IntelliJ IDEA یک رابط کاربری کاملاً مناسب برای کار با پایگاه داده ارائه می دهد. به نظر می رسد این است:
(واقع در صفحه سمت راست IDEA، تب Database). برای ایجاد یک اتصال، روی "+" کلیک کنید و منبع داده ما (PostgeSQL) را انتخاب کنید. فیلدهای مربوط به کاربر و پایگاه داده ("postgres" برای هر دوی آنها) را پر کنید و رمز عبوری که در هنگام نصب PostgreSQL تنظیم شده است را وارد کنید. در صورت لزوم، درایور Postgres را دانلود کنید. شما می توانید این کار را در همان صفحه انجام دهید. برای تأیید اینکه اتصال پایگاه داده برقرار است، روی "Test Connection" کلیک کنید. اگر "موفق" را می بینید، ادامه دهید. اکنون جداول مورد نیاز خود را ایجاد می کنیم. در مجموع دو مورد وجود خواهد داشت: کاربران و خودروها. پارامترهای جدول کاربران:
توجه داشته باشید که id کلید اصلی است. اگر نمی دانید کلید اصلی در SQL چیست، آن را در گوگل جستجو کنید. این مهم است. تنظیمات جدول خودکار:
برای جدول خودکار، باید یک کلید خارجی را پیکربندی کنید. این به پیوند جداول ما کمک خواهد کرد. توصیه می کنم در مورد آن بیشتر بخوانید. به بیان ساده، به یک جدول خارجی، در مورد ما، کاربران ارجاع می دهد. اگر خودرویی متعلق به کاربر با id = 1 باشد، فیلد user_id خودروها برابر با 1 خواهد بود. به این صورت است که ما کاربران را با خودروهای آنها در برنامه خود مرتبط می کنیم. در جدول autos ما، فیلد user_id به عنوان کلید خارجی عمل می کند. به فیلد id جدول کاربران اشاره خواهد کرد.
بنابراین، ما یک پایگاه داده با دو جدول ایجاد کرده ایم. آنچه باقی می ماند درک نحوه مدیریت آن از کد جاوا است. ما با فایل pom.xml شروع می کنیم، که در آن باید کتابخانه های لازم را قرار دهیم (در Maven به آنها وابستگی می گویند). تمام کتابخانه ها در مخزن مرکزی Maven ذخیره می شوند. کتابخانه هایی که در pom.xml مشخص می کنید برای استفاده در پروژه در دسترس شما هستند. pom.xml شما باید به این صورت باشد:
همانطور که می بینید هیچ چیز پیچیده ای نیست. ما فقط 2 وابستگی اضافه کردیم - برای استفاده از PostgreSQL و Hibernate. حالا بریم سراغ کد جاوا. تمام بسته ها و کلاس های لازم را در پروژه ایجاد کنید. برای شروع، ما به یک مدل داده نیاز داریم: the
حاشیه نویسی @OneToMany در بالای لیست قرار دارد. این بدان معنی است که چندین اتومبیل می توانند با یک شی از کلاس User مطابقت داشته باشند. عنصر "mappedBy" به فیلد کاربری کلاس اشاره دارد
Hibernate.cfg.xml در اینجا خوانده می شود: ![اولین برنامه Hibernate شما - 13]()
بیایید سعی کنیم نام کاربری خود را تغییر دهیم. جدول کاربران را پاک کنید و کد را اجرا کنید
اگر کاربر را حذف کنید چه؟ جدول کاربران را پاک کنید (خودکار خود پاک می شود) و کد را اجرا کنید

- IntelliJ IDEA Ultimate Edition
آن را از وب سایت رسمی دانلود کرده و نسخه آزمایشی 30 روزه را فعال کنید. - PostgreSQL - یکی از محبوب ترین سیستم های مدیریت پایگاه داده مدرن (DBMS)
- Maven (از قبل به IDEA متصل شده است)
- اندکی بردباری.
Hibernate چیست؟
این یکی از محبوبترین پیادهسازیهای نگاشت شی رابطهای (ORM) است. نگاشت شی رابطه ای رابطه بین اشیاء نرم افزار و رکوردهای پایگاه داده را تعریف می کند. البته Hibernate عملکرد بسیار گسترده ای دارد، اما ما بر روی ساده ترین عملکردها تمرکز خواهیم کرد. هدف ما ایجاد یک برنامه CRUD (ایجاد، خواندن، به روز رسانی، حذف) است که قادر به انجام موارد زیر باشد:- کاربران (کاربر) ایجاد کنید، آنها را با شناسه در پایگاه داده جستجو کنید، داده های آنها را در پایگاه داده به روز کنید و آنها را از پایگاه داده حذف کنید.
- تخصیص اشیاء خودرو (خودکار) به کاربران. ایجاد، به روز رسانی، یافتن و حذف خودروها از پایگاه داده.
- علاوه بر این، برنامه باید به طور خودکار خودروهای "بدون مالک" را از پایگاه داده حذف کند. به عبارت دیگر، هنگامی که یک کاربر حذف می شود، تمام خودروهای متعلق به آن کاربر نیز باید از پایگاه داده حذف شوند.


com.yourNickname.codegym
. این هیچ تاثیری روی برنامه نخواهد داشت. برای artifactId، هر نام پروژه ای را که دوست دارید انتخاب کنید. نسخه را می توان بدون تغییر رها کرد. 






User
and Auto
classs.
package models;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table (name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String name;
// You can omit the Column attribute if the name property matches the column name in the table
private int age;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Auto> autos;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
autos = new ArrayList<>();
}
public void addAuto(Auto auto) {
auto.setUser(this);
autos.add(auto);
}
public void removeAuto(Auto auto) {
autos.remove(auto);
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Auto> getAutos() {
return autos;
}
public void setAutos(List<Auto> autos) {
this.autos = autos;
}
@Override
public String toString() {
return "models.User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
package models;
import javax.persistence.*;
@Entity
@Table(name = "autos")
public class Auto {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column (name = "model")
private String model;
// You can omit the Column attribute if the name property matches the column name in the table
private String color;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
public Auto() {
}
public Auto(String model, String color) {
this.model = model;
this.color = color;
}
public int getId() {
return id;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return color + " " + model;
}
}
همانطور که می بینید، کلاس ها دارای یک دسته حاشیه نویسی مبهم هستند. بیایید شروع به کندوکاو در آنها کنیم. برای ما، حاشیه نویسی اصلی @Entity است. در مورد آن در ویکی پدیا بخوانید و همه چیز را از روی قلب یاد بگیرید. این پایه و اساس بنیاد است. این حاشیه نویسی به اشیاء کلاس جاوا اجازه می دهد تا به یک پایگاه داده نگاشت شوند. برای اینکه یک کلاس یک موجودیت باشد، باید شرایط زیر را برآورده کند:
- باید یک سازنده خالی (
public
یاprotected
) داشته باشد. - این نمی تواند تودرتو، یک رابط یا یک باشد
enum
- نمی تواند باشد
final
و نمی تواندfinal
فیلد/خواص داشته باشد - باید حداقل یک فیلد @Id داشته باشد.
- می تواند سازنده های غیر خالی داشته باشد
- می تواند به ارث برسد و به ارث برسد
- می تواند روش های دیگری داشته باشد و رابط ها را پیاده سازی کند.
User
کلاس بسیار شبیه به جدول کاربران است. دارای id
، name
و age
فیلدها است. حاشیهنویسیهایی که در بالای آنها قرار گرفتهاند نیازی به توضیح خاصی ندارند: واضح است که @Id نشان میدهد که فیلد شناسهای از اشیاء این کلاس است. حاشیهنویسی Table@ بالای کلاس، نام جدولی را نشان میدهد که اشیاء در آن نوشته شدهاند. به کامنت بالای فیلد سن توجه کنید: اگر نام فیلد در کلاس با نام جدول یکی باشد، می توانید حاشیه نویسی @Column را حذف کنید و کار خواهد کرد. در مورد قسمت مشخص شده در مهاربندها ("strategy = GenerationType.IDENTITY"): چندین استراتژی برای تولید شناسه ها وجود دارد. شما می توانید آنها را در گوگل جستجو کنید، اما برای برنامه ما، نیازی به زحمت نیست. نکته اصلی این است که برای اشیاء ما مقدار id به طور خودکار تولید می شود. بر این اساس، هیچ تنظیم کننده ای برای id وجود ندارد و آن را در سازنده نیز تنظیم نمی کنیم. با این حال، راه هایی وجود دارد که User
کلاس برجسته می شود. لیست ماشین ها داره! 
Auto
. بنابراین، خودروها و کاربران با هم مرتبط هستند. عنصر orphanRemoval نشان می دهد که آیا باید عملیات حذف را برای موجودیت هایی که دیگر رابطه ای ندارند اعمال شود یا خیر. اگر یک کاربر را از پایگاه داده حذف کنیم، تمام خودروهای مرتبط با آن نیز حذف خواهند شد. به نوبه خود، در Auto
کلاس، فیلد کاربری را با حاشیه نویسی @ManyToOne (یک کاربر می تواند با بسیاری از Autos مطابقت داشته باشد) و حاشیه نویسی @JoinColumn را مشاهده خواهید کرد. نشان می دهد که کدام ستون در جدول autos برای ارجاع به جدول کاربران (یعنی کلید خارجی که قبلاً در مورد آن صحبت کردیم) استفاده می شود. پس از ایجاد مدل داده، نوبت به آموزش برنامه خود می رسد که با داده های موجود در پایگاه داده عملیات انجام دهد. بیایید با کلاس ابزار HibernateSessionFactoryUtil شروع کنیم. این فقط یک کار دارد - ایجاد یک کارخانه جلسه برای برنامه ما برای کار با پایگاه داده (به الگوی طراحی کارخانه سلام کنید!). کار دیگری بلد نیست.
package utils;
import models.Auto;
import models.User;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateSessionFactoryUtil {
private static SessionFactory sessionFactory;
private HibernateSessionFactoryUtil() {}
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
Configuration configuration = new Configuration().configure();
configuration.addAnnotatedClass(User.class);
configuration.addAnnotatedClass(Auto.class);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
} catch (Exception e) {
System.out.println("Exception!" + e);
}
}
return sessionFactory;
}
}
در این کلاس، یک شی Configuration جدید ایجاد می کنیم و کلاس هایی را که باید به عنوان موجودیت ها در نظر گرفته شود، به آن ارسال می کنیم: User
و Auto
. به روش توجه کنید configuration.getProperties()
. چه خواص دیگری وجود دارد؟ آنها از کجا می آیند؟ ویژگی ها تنظیمات hibernate هستند که در فایل ویژه hibernate.cfg.xml نشان داده شده است. 
new Configuration().configure();
همانطور که می بینید، چیز خاصی در مورد آن وجود ندارد: شامل پارامترهای اتصال به پایگاه داده و همچنین پارامتر show_sql است. این مورد لازم است تا تمام کوئری های sql اجرا شده توسط Hibernate در کنسول نمایش داده شوند. به این ترتیب متوجه خواهید شد که Hibernate در هر لحظه دقیقاً چه کاری انجام می دهد و هر گونه حس "جادویی" را از بین می برد. بعد ما به UserDAO
کلاس نیاز داریم. بهترین روش برنامهنویسی از طریق رابطها است – ایجاد یک UserDAO
رابط و UserDAOImpl
پیادهسازی مجزا، اما برای کاهش مقدار کد از این کار صرفنظر میکنم. در پروژه های واقعی این کار را نکنید! الگوی طراحی DAO (شیء دسترسی به داده) یکی از رایج ترین الگوها است. ایده ساده است - یک لایه برنامه ایجاد کنید که فقط مسئول دسترسی به داده است، نه بیشتر. واکشی داده ها از پایگاه داده، به روز رسانی داده ها، حذف داده ها - همین. درباره DAO بیشتر مطالعه کنید. شما از اشیاء دسترسی به داده به طور مداوم در کار خود استفاده خواهید کرد. کلاس ما چه کاری می تواند UserDao
انجام دهد؟ خوب، مانند همه DAO ها، فقط می تواند با داده کار کند. کاربر را با شناسه پیدا کنید، دادههای آن را بهروزرسانی کنید، آنها را حذف کنید، فهرستی از همه کاربران را از پایگاه داده دریافت کنید، یا یک کاربر جدید را در پایگاه داده ذخیره کنید — این تمام عملکرد آن است.
package dao;
import models.Auto;
import models.User;
import org.hibernate.Session;
import org.hibernate.Transaction;
import utils.HibernateSessionFactoryUtil;
import java.util.List;
public class UserDao {
public User findById(int id) {
return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(User.class, id);
}
public void save(User user) {
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx1 = session.beginTransaction();
session.save(user);
tx1.commit();
session.close();
}
public void update(User user) {
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx1 = session.beginTransaction();
session.update(user);
tx1.commit();
session.close();
}
public void delete(User user) {
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx1 = session.beginTransaction();
session.delete(user);
tx1.commit();
session.close();
}
public Auto findAutoById(int id) {
return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(Auto.class, id);
}
public List<User> findAll() {
List<User> users = (List<User>) HibernateSessionFactoryUtil.getSessionFactory().openSession().createQuery("From User").list();
return users;
}
}
UserDao
روش های 's مشابه یکدیگر است. در اکثر آنها، ما یک شی Session
(جلسه اتصال پایگاه داده) را با استفاده از Session Factory دریافت می کنیم، یک تراکنش واحد را در این جلسه ایجاد می کنیم، دستکاری داده های لازم را انجام می دهیم، نتیجه تراکنش را در پایگاه داده ذخیره می کنیم و سپس جلسه را می بندیم. خود روش ها، همانطور که می بینید، بسیار ساده هستند. DAO "قلب" برنامه ما است. با این حال، ما مستقیماً یک DAO ایجاد نمی کنیم و متدهای آن را در main()
متد خود فراخوانی نمی کنیم. تمام منطق به کلاس منتقل می شود UserService
.
package services;
import dao.UserDao;
import models.Auto;
import models.User;
import java.util.List;
public class UserService {
private UserDao usersDao = new UserDao();
public UserService() {
}
public User findUser(int id) {
return usersDao.findById(id);
}
public void saveUser(User user) {
usersDao.save(user);
}
public void deleteUser(User user) {
usersDao.delete(user);
}
public void updateUser(User user) {
usersDao.update(user);
}
public List<User> findAllUsers() {
return usersDao.findAll();
}
public Auto findAutoById(int id) {
return usersDao.findAutoById(id);
}
}
یک سرویس یک لایه داده برنامه است که مسئول اجرای منطق تجاری است. اگر برنامه شما نیاز به اجرای نوعی منطق تجاری دارد، این کار را از طریق خدمات انجام می دهد. یک سرویس حاوی a است UserDao
و متدهای DAO را در متدهای خود فراخوانی می کند. ممکن است به نظر برسد که ما در اینجا توابع را کپی می کنیم (چرا فقط متدها را از یک شی DAO فراخوانی نکنیم؟)، اما با تعداد زیادی اشیاء و منطق پیچیده، لایه بندی برنامه مزایای بسیار زیادی را ارائه می دهد (انجام این کار تمرین خوبی است - این را در آینده به خاطر بسپارید. و در مورد "لایه های برنامه" بخوانید). سرویس ما منطق سادهای دارد، اما روشهای سرویس در پروژههای دنیای واقعی حاوی بیش از یک خط کد هستند :) حالا همه چیزهایی را که برای اجرای برنامه نیاز دارید در اختیار داریم! در main()
روش، بیایید یک کاربر و ماشینش ایجاد کنیم، یکی را با دیگری مرتبط کنیم و در پایگاه داده ذخیره کنیم.
import models.Auto;
import models.User;
import services.UserService;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
UserService userService = new UserService();
User user = new User ("Jenny", 26);
userService.saveUser(user);
Auto ferrari = new Auto("Ferrari", "red");
ferrari.setUser(user);
user.addAuto(ferrari);
Auto ford = new Auto("Ford", "black");
ford.setUser(user);
user.addAuto(ford);
userService.updateUser(user);
}
}
همانطور که می بینید، جدول کاربران رکورد خاص خود را دارد و جدول autos رکورد خود را دارد. 

import models.Auto;
import models.User;
import services.UserService;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
UserService userService = new UserService();
User user = new User ("Jenny", 26);
userService.saveUser(user);
Auto ferrari = new Auto("Ferrari", "red");
user.addAuto(ferrari);
Auto ford = new Auto("Ford", "black");
ford.setUser(user);
user.addAuto(ford);
userService.updateUser(user);
user.setName ("Benny");
userService.updateUser(user);
}
}
کار می کند! 
import models.Auto;
import models.User;
import services.UserService;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
UserService userService = new UserService();
User user = new User ("Jenny", 26);
userService.saveUser(user);
Auto ferrari = new Auto("Ferrari", "red");
user.addAuto(ferrari);
Auto ford = new Auto("Ford", "black");
ford.setUser(user);
user.addAuto(ford);
userService.updateUser(user);
user.setName ("Benny");
userService.updateUser(user);
userService.deleteUser(user);
}
}
و جداول ما کاملا خالی است (به کنسول توجه کنید - تمام درخواست های انجام شده توسط Hibernate در آنجا نمایش داده می شود). می توانید با برنامه بازی کنید و تمام عملکردهای آن را امتحان کنید. به عنوان مثال، یک کاربر با ماشین ها ایجاد کنید، آن را در پایگاه داده ذخیره کنید، به شناسه اختصاص داده شده به کاربر نگاه کنید و سعی کنید از این شناسه در روشی استفاده کنید main()
تا کاربر را از پایگاه داده واکشی کنید و لیستی از ماشین های آن را در کنسول نمایش دهید. . البته، ما تنها بخش کوچکی از عملکرد Hibernate را دیدهایم. قابلیتهای آن بسیار گسترده است و مدتهاست که یک ابزار استاندارد صنعتی برای توسعه جاوا بوده است. اگر می خواهید آن را با جزئیات مطالعه کنید، می توانم کتاب "Java Persistence API and Hibernate" را توصیه کنم. در مقاله قبلی بررسی کردم. امیدوارم این مقاله برای خوانندگان مفید بوده باشد. اگر سوالی دارید در نظرات بپرسید. خوشحال میشم جواب بدم :) همچنین یادتون نره با ارسال "لایک" از نویسنده در مسابقه حمایت کنید. یا بهتر از آن - "آن را دوست دارم" :) در مطالعات خود موفق باشید!
GO TO FULL VERSION