CodeGym /Blog Java /Aleatoriu /Prima ta aplicație Hibernate
John Squirrels
Nivel
San Francisco

Prima ta aplicație Hibernate

Publicat în grup
În acest articol, vă veți familiariza cu unul dintre cele mai populare cadre de afaceri pentru Java și vă veți crea prima aplicație Hibernate. Nu ai auzit de Hibernate? Sau poate ai auzit de el, dar nu l-ai folosit? Sau poate ai încercat să-l folosești, dar nu ai reușit? În toate cele trei cazuri - bine ați venit la sub tăietură :) Prima ta aplicație Hibernate - 1 Salut, tuturor! În acest articol, voi vorbi despre principalele caracteristici ale cadrului Hibernate și vă voi ajuta să scrieți prima dvs. mini-aplicație. Pentru aceasta avem nevoie de:
  1. IntelliJ IDEA Ultimate Edition
    Descărcați-l de pe site-ul oficial și activați versiunea de încercare de 30 de zile.
  2. PostgreSQL - unul dintre cele mai populare sisteme moderne de gestionare a bazelor de date (DBMS)
  3. Maven (deja conectat la IDEA)
  4. Puțină răbdare.
Pentru orice eventualitate, am postat codul aplicației pe GitHub (ramura codegym). Articolul se adresează în primul rând celor care nu au lucrat niciodată cu această tehnologie înainte, așa că am redus la minimum cantitatea de cod. Să începem!

Ce este Hibernate?

Este una dintre cele mai populare implementări de mapare obiect-relațională (ORM). O mapare obiect-relațională definește relația dintre obiectele software și înregistrările bazei de date. Desigur, Hibernate are o funcționalitate foarte largă, dar ne vom concentra pe cele mai simple funcții. Scopul nostru este de a crea o aplicație CRUD (Create, Read, Update, Delete) care va fi capabilă să:
  1. Creați utilizatori (Utilizator), căutați-i în baza de date după ID, actualizați-le datele din baza de date și ștergeți-i din baza de date.
  2. Atribuiți obiecte mașini (Auto) utilizatorilor. Creați, actualizați, găsiți și ștergeți mașini din baza de date.
  3. În plus, aplicația ar trebui să elimine automat mașinile „fără proprietar” din baza de date. Cu alte cuvinte, atunci când un utilizator este șters, toate mașinile care aparțin acelui utilizator trebuie, de asemenea, să fie șterse din baza de date.
Proiectul nostru va fi structurat astfel: Prima ta aplicație Hibernate - 2După cum puteți vedea, nimic complicat. 6 clase + 1 fisier cu configuratii. Mai întâi, creați un nou proiect Maven în IntelliJ IDEA. Fișier -> Proiect nou. Selectați Maven dintre tipurile de proiecte propuse și treceți la pasul următor. Prima ta aplicație Hibernate - 3Apache Maven este un cadru pentru construirea automată a proiectelor bazate pe o descriere a structurii lor în fișiere POM. Întreaga structură a proiectului dumneavoastră va fi descrisă în pom.xml, un fișier pe care IDEA însuși îl va crea în rădăcina proiectului dumneavoastră. În setările proiectului, trebuie să specificați următoarele setări Maven: groupId și artefactId. În proiecte, groupId este de obicei o descriere a companiei sau a unității de afaceri. Numele de domeniu al companiei sau al site-ului web poate merge aici. La rândul său, artefactId este numele proiectului. Pentru groupdId, puteți introduce com.yourNickname.codegym. Acest lucru nu va avea niciun efect asupra aplicației. Pentru artefactId, alegeți orice nume de proiect doriți. Versiunea poate fi lăsată neschimbată. Prima ta aplicație Hibernate - 4Pe ultimul ecran, pur și simplu confirmați datele introduse anterior.Prima ta aplicație Hibernate - 5Deci, am creat proiectul. Acum tot ce mai rămâne de făcut este să scriem niște cod și să-l facem să funcționeze :) În primul rând: dacă vrem să creăm o aplicație care să funcționeze cu o bază de date, cu siguranță nu ne putem lipsi de o bază de date! Descărcați PostgreSQL de aici (folosesc versiunea 9). PostgreSQL are un utilizator implicit „postgres” - va trebui să vă gândiți la o parolă pentru acesta când îl instalați. Nu uitați parola. O să avem nevoie mai târziu! (În general, utilizarea bazei de date implicite în aplicații este o practică proastă, dar o vom face pentru a reduce numărul de cauze ale ulcerelor prin crearea propriei baze de date). Dacă nu sunteți prieten cu linia de comandă și interogările SQL, există vești bune. IntelliJ IDEA oferă o interfață de utilizator complet adecvată pentru lucrul cu baza de date. Prima ta aplicație Hibernate - 6(situat în panoul din dreapta al IDEA, fila Bază de date). Pentru a crea o conexiune, faceți clic pe „+” și selectați sursa noastră de date (PostgeSQL). Completați câmpurile pentru utilizator și baza de date („postgres” pentru ambele) și introduceți parola care a fost setată în timpul instalării PostgreSQL. Dacă este necesar, descărcați driverul Postgres. Puteți face acest lucru pe aceeași pagină. Faceți clic pe „Testează conexiunea” pentru a verifica dacă conexiunea la baza de date este stabilită. Dacă vedeți „Reușit”, treceți mai departe. Acum vom crea tabelele de care avem nevoie. Vor fi în total două: utilizatori și auto. Parametri pentru tabelul utilizatori: Prima ta aplicație Hibernate - 7rețineți că id este cheia primară. Dacă nu știți care este cheia primară în SQL, căutați-o pe Google. Asta e important. Setări pentru tabelul auto: Prima ta aplicație Hibernate - 8Pentru tabelul autos, trebuie să configurați o cheie străină. Va servi pentru a lega tabelele noastre. Vă recomand să citiți mai multe despre el. Mai simplu, se referă la un tabel extern, în cazul nostru, utilizatori. Dacă o mașină aparține utilizatorului cu id = 1, atunci câmpul user_id al mașinilor va fi egal cu 1. Așa asociem utilizatorii cu mașinile lor în aplicația noastră. În tabelul nostru autos, câmpul user_id va acționa ca cheie externă. Se va referi la câmpul ID din tabelul utilizatorilor. Prima ta aplicație Hibernate - 9Deci, am creat o bază de date cu două tabele. Ceea ce rămâne este să înțelegeți cum să-l gestionați din codul Java. Vom începe cu fișierul pom.xml, în care trebuie să includem bibliotecile necesare (în Maven se numesc dependențe). Toate bibliotecile sunt stocate în depozitul central Maven. Bibliotecile pe care le specificați în pom.xml sunt disponibile pentru a le utiliza în proiect. Pom.xml ar trebui să arate astfel: Prima ta aplicație Hibernate - 10Nimic complicat, după cum puteți vedea. Am adăugat doar 2 dependențe - pentru utilizarea PostgreSQL și Hibernate. Acum să trecem la codul Java. Creați toate pachetele și clasele necesare în proiect. Pentru a începe, avem nevoie de un model de date: clasele Userși Auto.

 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;
     }
 }
 
 
După cum puteți vedea, cursurile au o grămadă de adnotări obscure. Să începem să sapă în ele. Pentru noi, adnotarea principală este @Entity. Citește despre asta pe Wikipedia și învață totul pe de rost. Aceasta este fundația fundației. Această adnotare permite ca obiectele clasei dvs. Java să fie mapate la o bază de date. Pentru ca o clasă să fie o entitate, aceasta trebuie să îndeplinească următoarele cerințe:
  • Trebuie să aibă un constructor gol ( publicsau protected)
  • Nu poate fi imbricat, o interfață sau unenum
  • Nu poate fi finalși nu poate avea finalcâmpuri/proprietăți
  • Trebuie să aibă cel puțin un câmp @Id.
Verificați-vă cursurile de entitate: sunt locuri foarte populare pentru a vă împușca în picior. Este foarte ușor să uiți ceva. În plus, o entitate poate face următoarele:
  • Poate avea constructori non-vid
  • Poate moșteni și poate fi moștenit
  • Poate avea alte metode și poate implementa interfețe.
După cum puteți vedea, Userclasa este foarte asemănătoare cu tabelul utilizatorilor. Are id, name, șiagecâmpuri. Adnotările situate deasupra lor nu au nevoie de nicio explicație anume: este clar că @Id indică faptul că câmpul este un identificator al obiectelor acestei clase. Adnotarea @Table de deasupra clasei indică numele tabelului în care sunt scrise obiectele. Observați comentariul de deasupra câmpului de vârstă: dacă numele câmpului din clasă este același cu numele tabelului, puteți omite adnotarea @Column și va funcționa. În ceea ce privește partea indicată în acolade ("strategy = GenerationType.IDENTITY"): există mai multe strategii pentru generarea ID-urilor. Le puteți pe Google, dar pentru aplicația noastră, nu trebuie să vă deranjați. Principalul lucru este că pentru obiectele noastre valoarea id va fi generată automat. În consecință, nu există un setter pentru id și nici nu îl setăm în constructor. In orice caz,Userclasa iese în evidență. Are o listă de mașini! Prima ta aplicație Hibernate - 11Adnotarea @OneToMany se blochează deasupra listei. Înseamnă că mai multe mașini pot corespunde aceluiași obiect al clasei User. Elementul „mappedBy” se referă la câmpul utilizator al Autoclasei. Astfel, mașinile și utilizatorii sunt legate. Elementul orphanRemoval indică dacă se aplică operația de eliminare la entitățile care nu mai au o relație. Dacă ștergem un utilizator din baza de date, atunci toate mașinile asociate cu acesta vor fi și ele șterse. La rândul său, înAutoclasa, veți vedea câmpul utilizator cu adnotarea @ManyToOne (un utilizator poate corespunde mai multor Auto) și adnotarea @JoinColumn. Indică ce coloană din tabelul auto este folosită pentru a face referire la tabelul utilizatori (adică cheia externă despre care am vorbit mai devreme). După crearea modelului de date, este timpul să învățăm programul nostru să efectueze operații cu datele din baza de date. Să începem cu clasa de utilitate HibernateSessionFactoryUtil. Are o singură sarcină — să creeze o fabrică de sesiuni pentru ca aplicația noastră să funcționeze cu baza de date (să salutați modelul de design Factory!). Nu știe să facă altceva.

 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("Исключение!" + e);
             }
         }
         return sessionFactory;
     }
 }
 
În această clasă, creăm un nou obiect Configuration și îi transmitem clasele pe care ar trebui să le trateze ca entități: Userși Auto. Acordați atenție metodei configuration.getProperties(). Ce alte proprietăți există? De unde vin ei? Proprietățile sunt setările de hibernare indicate în fișierul special hibernate.cfg.xml. Prima ta aplicație Hibernate - 12Hibernate.cfg.xml se citește aici: new Configuration().configure(); După cum vedeți, nu este nimic deosebit de special în el: conține parametrii pentru conectarea la baza de date, precum și parametrul show_sql. Acest lucru este necesar pentru ca toate interogările sql executate de Hibernate să fie afișate pe consolă. În acest fel, vei vedea exact ce face Hibernate în orice moment, eliminând orice sentiment de „magie”. În continuare avem nevoie deUserDAOclasă. Cea mai bună practică este să programați prin interfețe - să creați o UserDAOinterfață și UserDAOImplo implementare separată, dar voi omite acest lucru pentru a reduce cantitatea de cod. Nu faceți asta în proiecte reale! Modelul de design DAO (obiect de acces la date) este unul dintre cele mai comune. Ideea este simplă — creați un strat de aplicație responsabil doar pentru accesarea datelor, nimic mai mult. Preluați date din baza de date, actualizați datele, ștergeți datele - asta este. Studiați mai multe despre DAO. Veți folosi în mod constant obiectele de acces la date în munca dvs. Ce poate UserDaoface clasa noastră? Ei bine, ca toate DAO-urile, poate funcționa numai cu date. Găsiți un utilizator după id, actualizați-i datele, ștergeți-l, obțineți o listă cu toți utilizatorii din baza de date sau salvați un utilizator nou în baza de date - aceasta este întreaga funcționalitate a acestuia.

 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;
     }
 }
 
UserDaometodele lui sunt similare una cu cealaltă. În cele mai multe dintre ele, obținem un obiect Session (sesiunea de conexiune la baza de date) folosind Session Factory, creăm o singură tranzacție în cadrul acestei sesiuni, efectuăm manipulările necesare de date, salvăm rezultatul tranzacției în baza de date și apoi închidem sesiunea. Metodele în sine, după cum puteți vedea, sunt destul de simple. DAO este „inima” aplicației noastre. Cu toate acestea, nu vom crea direct un DAO și nu vom apela metodele sale în main()metoda noastră. Toată logica va fi mutată în UserServiceclasă.

 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);
     }
 
 
 }
 
 
Un serviciu este un strat de date al aplicației responsabil pentru executarea logicii de afaceri. Dacă programul dvs. trebuie să execute un fel de logică de afaceri, o face prin intermediul serviciilor. Un serviciu conține un UserDaoși apelează metode DAO în metodele sale. Poate părea că duplicăm funcții aici (de ce nu apelăm doar metodele dintr-un obiect DAO?), dar cu o mulțime de obiecte și o logică complexă, stratificarea aplicației oferă avantaje uriașe (a face acest lucru este o bună practică - rețineți acest lucru în viitor și citiți despre „straturile de aplicare”). Serviciul nostru are o logică simplă, dar metodele de service din proiectele din lumea reală conțin mult mai mult de o linie de cod :) Acum avem tot ce aveți nevoie pentru a rula aplicația! În main()metodă, să creăm un utilizator și mașina lui, să asociem unul cu celălalt și să le salvăm în baza de date.

 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);
     }
 }
 
 
După cum puteți vedea, tabelul utilizatori are propria sa înregistrare, iar tabelul autos are propria sa înregistrare. Prima ta aplicație Hibernate - 13Prima ta aplicație Hibernate - 14Să încercăm să redenumim utilizatorul nostru. Ștergeți tabelul de utilizatori și executați codul

 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);
     }
 }
 
 
Funcționează! Prima ta aplicație Hibernate - 15Ce se întâmplă dacă ștergeți utilizatorul? Ștergeți tabelul utilizatorilor (autos se va șterge singur) și executa codul

 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);
     }
 }
 
 
Și tabelele noastre sunt complet goale (atenție la consolă — toate solicitările efectuate de Hibernate vor fi afișate acolo). Puteți să vă jucați cu aplicația și să încercați toate funcțiile acesteia. De exemplu, creați un utilizator cu mașini, salvați-l în baza de date, uitați-vă la id-ul atribuit utilizatorului și încercați să utilizați acest id înmain()metodă de a prelua utilizatorul din baza de date și de a afișa o listă a mașinilor sale pe consolă. Desigur, am văzut doar o mică parte din funcționalitatea Hibernate. Capacitățile sale sunt foarte largi și a fost mult timp un instrument standard al industriei pentru dezvoltarea Java. Dacă doriți să o studiați în detaliu, vă pot recomanda cartea „Java Persistence API and Hibernate”. Am trecut în revistă într-un articol anterior. Sper că acest articol a fost de ajutor cititorilor. Dacă aveți întrebări, adresați-le în comentarii. Voi răspunde cu plăcere :) De asemenea, nu uitați să susțineți autorul în concurs postând un „Like”. Sau și mai bine — „Love it” :) Mult succes la studii!
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION