CodeGym /Java Blog /Willekeurig /Je eerste Hibernate-applicatie
John Squirrels
Niveau 41
San Francisco

Je eerste Hibernate-applicatie

Gepubliceerd in de groep Willekeurig
In dit artikel maakt u kennis met een van de meest populaire enterprise-frameworks voor Java en maakt u uw eerste Hibernate-toepassing. Nog nooit van Hibernate gehoord? Of misschien heb je er wel eens van gehoord, maar nog niet gebruikt? Of misschien heb je geprobeerd het te gebruiken, maar is het niet gelukt? In alle drie de gevallen - welkom onder de snit :) Uw eerste Hibernate-toepassing - 1 Hallo allemaal! In dit artikel zal ik het hebben over de belangrijkste functies van het Hibernate-framework en zal ik je helpen bij het schrijven van je eerste mini-applicatie. Hiervoor hebben we nodig:
  1. IntelliJ IDEA Ultimate Edition
    Download het van de officiële website en activeer de proefversie van 30 dagen.
  2. PostgreSQL - een van de meest populaire moderne databasebeheersystemen (DBMS)
  3. Maven (al aangesloten op IDEA)
  4. Een beetje geduld.
Voor het geval dat ik de applicatiecode op GitHub (codegym-tak) heb gepost. Het artikel is in de eerste plaats bedoeld voor degenen die nog nooit met deze technologie hebben gewerkt, dus ik heb de hoeveelheid code geminimaliseerd. Laten we beginnen!

Wat is overwinteren?

Het is een van de meest populaire ORM-implementaties (Object-Relational Mapping). Een object-relationele mapping definieert de relatie tussen software-objecten en databaserecords. Natuurlijk heeft Hibernate een zeer brede functionaliteit, maar we zullen ons concentreren op de eenvoudigste functies. Ons doel is om een ​​CRUD-applicatie (Create, Read, Update, Delete) te maken die in staat zal zijn om:
  1. Maak gebruikers aan (User), zoek ze in de database op ID, update hun gegevens in de database en verwijder ze uit de database.
  2. Wijs auto-objecten (Auto) toe aan gebruikers. Maak, update, zoek en verwijder auto's uit de database.
  3. Bovendien zou de applicatie auto's zonder eigenaar automatisch uit de database moeten verwijderen. Met andere woorden, wanneer een gebruiker wordt verwijderd, moeten ook alle auto's van die gebruiker uit de database worden verwijderd.
Ons project zal als volgt worden gestructureerd: Uw eerste Hibernate-toepassing - 2Zoals u kunt zien, niets ingewikkelds. 6 klassen + 1 bestand met configuraties. Maak eerst een nieuw Maven-project in IntelliJ IDEA. Bestand -> Nieuw project. Selecteer Maven uit de voorgestelde projecttypes en ga naar de volgende stap. Uw eerste Hibernate-toepassing - 3Apache Maven is een raamwerk voor het automatisch bouwen van projecten op basis van een beschrijving van hun structuur in POM-bestanden. De volledige structuur van uw project wordt beschreven in pom.xml, een bestand dat IDEA zelf aanmaakt in de root van uw project. In de projectinstellingen moet u de volgende Maven-instellingen opgeven: groupId en artifactId. In projecten is groupId meestal een beschrijving van het bedrijf of de business unit. Hier kan de domeinnaam van het bedrijf of de website komen. Op zijn beurt is artifactId de naam van het project. Voor groupdId kunt u invoeren com.yourNickname.codegym. Dit heeft geen invloed op de toepassing. Kies voor artefactId een gewenste projectnaam. De versie kan ongewijzigd worden gelaten. Uw eerste Hibernate-toepassing - 4Op het laatste scherm bevestigt u eenvoudig de eerder ingevoerde gegevens.Uw eerste Hibernate-toepassing - 5Dus hebben we het project gemaakt. Nu rest ons alleen nog wat code te schrijven en het te laten werken :) Allereerst: als we een applicatie willen maken die met een database werkt, kunnen we zeker niet zonder een database! Download PostgreSQL hier (ik gebruik versie 9). PostgreSQL heeft een standaardgebruiker 'postgres' - u moet er een wachtwoord voor bedenken tijdens de installatie. Vergeet het wachtwoord niet. We hebben het later nodig! (Over het algemeen is het gebruik van de standaarddatabase in toepassingen een slechte gewoonte, maar we doen dit om het aantal oorzaken van zweren te verminderen door uw eigen database te maken). Als u geen vrienden bent met de opdrachtregel en SQL-query's, is er goed nieuws. IntelliJ IDEA biedt een geheel geschikte gebruikersinterface voor het werken met de database. Uw eerste Hibernate-toepassing - 6(bevindt zich in het rechterdeelvenster van IDEA, het tabblad Database). Om een ​​verbinding tot stand te brengen, klikt u op "+" en selecteert u onze gegevensbron (PostgeSQL). Vul de velden in voor de gebruiker en de database ("postgres" voor beide) en voer het wachtwoord in dat is ingesteld tijdens de installatie van PostgreSQL. Download indien nodig het Postgres-stuurprogramma. Dit doe je op dezelfde pagina. Klik op "Test Connection" om te controleren of de databaseverbinding tot stand is gebracht. Als je "Succesvol" ziet, ga dan verder. Nu gaan we de tabellen maken die we nodig hebben. Er zullen er in totaal twee zijn: gebruikers en auto's. Parameters voor de gebruikerstabel: Uw eerste Hibernate-toepassing - 7Merk op dat id de primaire sleutel is. Als u niet weet wat de primaire sleutel is in SQL, Google het dan. Dit is belangrijk. Instellingen voor automatische tabel: Uw eerste Hibernate-toepassing - 8Voor de autos-tabel moet u een externe sleutel configureren. Het zal dienen om onze tabellen te koppelen. Ik raad je aan er meer over te lezen. Simpel gezegd, het verwijst naar een externe tabel, in ons geval gebruikers. Als een auto van de gebruiker is met id = 1, dan is het veld user_id van de auto's gelijk aan 1. Op deze manier associëren we gebruikers met hun auto's in onze applicatie. In onze autos-tabel fungeert het veld user_id als externe sleutel. Het zal verwijzen naar het id-veld van de gebruikerstabel. Uw eerste Hibernate-toepassing - 9We hebben dus een database gemaakt met twee tabellen. Wat overblijft, is begrijpen hoe het vanuit Java-code moet worden beheerd. We beginnen met het bestand pom.xml, waarin we de benodigde bibliotheken moeten opnemen (in Maven worden ze afhankelijkheden genoemd). Alle bibliotheken worden opgeslagen in de centrale Maven-repository. De bibliotheken die u opgeeft in pom.xml zijn beschikbaar voor gebruik in het project. Uw pom.xml zou er zo uit moeten zien: Uw eerste Hibernate-toepassing - 10Niets ingewikkelds, zoals u kunt zien. We hebben slechts 2 afhankelijkheden toegevoegd - voor het gebruik van PostgreSQL en Hibernate. Laten we nu verder gaan met de Java-code. Maak alle benodigde pakketten en klassen in het project. Om te beginnen hebben we een gegevensmodel nodig: de klassen Useren .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;
     }
 }
 
 
Zoals je kunt zien, hebben klassen een aantal obscure annotaties. Laten we beginnen met ze in te graven. Voor ons is de belangrijkste annotatie @Entity. Lees erover op Wikipedia en leer het allemaal uit je hoofd. Dit is de basis van de stichting. Met deze annotatie kunnen objecten van uw Java-klasse worden toegewezen aan een database. Om een ​​klasse een entiteit te laten zijn, moet deze aan de volgende vereisten voldoen:
  • Het moet een lege constructor hebben ( publicof protected)
  • Het kan niet worden genest, een interface of eenenum
  • Het kan en kan geen velden/eigenschappen finalhebbenfinal
  • Het moet ten minste één @Id-veld hebben.
Controleer je entiteitsklassen: het zijn erg populaire plaatsen om jezelf in de voet te schieten. Het is heel gemakkelijk om iets te vergeten. Bovendien kan een entiteit het volgende doen:
  • Het kan niet-lege constructors hebben
  • Het kan erven en geërfd worden
  • Het kan andere methoden hebben en interfaces implementeren.
Zoals je kunt zien, Userlijkt de klasse erg op de gebruikerstabel. Het heeft id, name, enagevelden. De annotaties die erboven staan ​​hebben geen specifieke uitleg nodig: het is duidelijk dat @Id aangeeft dat het veld een identifier is van objecten van deze klasse. De @Table-annotatie boven de klasse geeft de naam aan van de tabel waarin de objecten zijn geschreven. Let op de opmerking boven het leeftijdsveld: als de naam van het veld in de klas hetzelfde is als de naam van de tabel, kunt u de @Column-annotatie weglaten en het zal werken. Wat betreft het deel dat tussen de accolades staat ("strategy = GenerationType.IDENTITY"): er zijn verschillende strategieën om ID's te genereren. U kunt ze googlen, maar voor onze toepassing hoeft u zich geen zorgen te maken. Het belangrijkste is dat voor onze objecten de waarde van id automatisch wordt gegenereerd. Dienovereenkomstig is er geen setter voor id, en we stellen het ook niet in de constructor in. Echter,Userklasse springt er uit. Het heeft een lijst met auto's! Uw eerste Hibernate-toepassing - 11De annotatie @OneToMany hangt boven de lijst. Dit betekent dat meerdere auto's kunnen overeenkomen met hetzelfde object van de User-klasse. Het element "mappedBy" verwijst naar het gebruikersveld van de Autoklasse. Auto's en gebruikers zijn dus aan elkaar gerelateerd. Het element weesRemoval geeft aan of de verwijderbewerking moet worden toegepast op entiteiten die geen relatie meer hebben. Als we een gebruiker uit de database verwijderen, worden ook alle auto's die eraan gekoppeld zijn verwijderd. Op zijn beurt in deAutoclass, ziet u het gebruikersveld met de @ManyToOne-annotatie (één gebruiker kan overeenkomen met veel Auto's) en de @JoinColumn-annotatie. Het geeft aan welke kolom in de autos-tabel wordt gebruikt om naar de gebruikerstabel te verwijzen (dwz de externe sleutel waar we het eerder over hadden). Nadat het datamodel is gemaakt, is het tijd om ons programma te leren bewerkingen uit te voeren met de gegevens in de database. Laten we beginnen met de klasse HibernateSessionFactoryUtil. Het heeft maar één taak: een sessiefabriek maken zodat onze applicatie met de database kan werken (zeg hallo tegen het Factory-ontwerppatroon!). Het weet niet hoe het anders moet.

 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;
     }
 }
 
In deze klasse maken we een nieuw configuratieobject en geven het de klassen door die het als entiteiten moet behandelen: Useren Auto. Let op de configuration.getProperties()methode. Welke andere eigenschappen zijn er? Waar komen ze vandaan? Eigenschappen zijn de slaapstandinstellingen die worden aangegeven in het speciale bestand hibernate.cfg.xml. Uw eerste Hibernate-toepassing - 12Hibernate.cfg.xml wordt hier gelezen: new Configuration().configure(); Zoals u ziet, is er niets bijzonders aan: het bevat de parameters voor verbinding met de database, evenals de parameter show_sql. Dit is vereist zodat alle sql-query's die door Hibernate worden uitgevoerd, op de console worden weergegeven. Op deze manier zie je precies wat Hibernate op een bepaald moment aan het doen is, en elimineer je elk gevoel van "magie". Vervolgens hebben we deUserDAOklas. De beste praktijk is om via de interfaces te programmeren — maak een aparte UserDAOinterface en UserDAOImplimplementatie, maar ik zal dit overslaan om de hoeveelheid code te verminderen. Doe dit niet in echte projecten! Het DAO-ontwerppatroon (data access object) is een van de meest voorkomende. Het idee is eenvoudig: maak een applicatielaag die alleen verantwoordelijk is voor toegang tot gegevens, niets meer. Gegevens ophalen uit de database, gegevens bijwerken, gegevens verwijderen - dat is alles. Lees meer over DAO. In uw werk gebruikt u voortdurend objecten voor gegevenstoegang. Wat kan onze UserDaoklas doen? Zoals alle DAO's kan het alleen met gegevens werken. Zoek een gebruiker op id, werk de gegevens bij, verwijder deze, haal een lijst op met alle gebruikers uit de database of sla een nieuwe gebruiker op in de database - dat is de volledige functionaliteit.

 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;
     }
 }
 
UserDaoDe methodes lijken op elkaar. In de meeste daarvan krijgen we een Session- object (databaseverbindingssessie) met behulp van onze Session Factory, maken we een enkele transactie binnen deze sessie, voeren we de nodige gegevensmanipulaties uit, slaan we het resultaat van de transactie op in de database en sluiten we de sessie. De methoden zelf zijn, zoals u kunt zien, vrij eenvoudig. DAO is het "hart" van onze applicatie. We zullen echter niet rechtstreeks een DAO maken en de methoden ervan in onze main()methode aanroepen. Alle logica wordt verplaatst naar de UserServiceklasse.

 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);
     }
 
 
 }
 
 
Een service is een applicatiegegevenslaag die verantwoordelijk is voor het uitvoeren van bedrijfslogica. Als uw programma een soort bedrijfslogica moet uitvoeren, gebeurt dit via services. Een service bevat een UserDaoen roept DAO-methoden op in zijn methoden. Het lijkt misschien alsof we hier functies dupliceren (waarom de methoden niet gewoon vanuit een DAO-object aanroepen?), maar met veel objecten en complexe logica biedt het aanbrengen van lagen enorme voordelen (dit is een goede gewoonte - onthoud dit in de toekomst en lees over "applicatielagen"). Onze service heeft eenvoudige logica, maar servicemethoden in real-world projecten bevatten veel meer dan één regel code :) Nu hebben we alles wat je nodig hebt om de applicatie uit te voeren! main()Laten we in de methode een gebruiker en zijn auto maken, de ene aan de andere koppelen en deze in de database opslaan.

 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);
     }
 }
 
 
Zoals u kunt zien, heeft de gebruikerstabel zijn eigen record en de autos-tabel heeft zijn eigen record. Uw eerste Hibernate-toepassing - 13Uw eerste Hibernate-toepassing - 14Laten we proberen onze gebruiker een andere naam te geven. Wis de gebruikerstabel en voer de code uit

 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);
     }
 }
 
 
Het werkt! Uw eerste Hibernate-toepassing - 15Wat als u de gebruiker verwijdert? Wis de gebruikerstabel (auto's wissen zichzelf) en voer de code uit

 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);
     }
 }
 
 
En onze tabellen zijn helemaal leeg (let op de console - alle verzoeken die door Hibernate worden uitgevoerd, worden daar weergegeven). Je kunt spelen met de applicatie en alle functies uitproberen. Maak bijvoorbeeld een gebruiker aan met auto's, sla deze op in de database, kijk naar de id die aan de gebruiker is toegewezen en probeer deze id te gebruiken in demain()methode om de gebruiker uit de database op te halen en een lijst met zijn auto's op de console weer te geven. Natuurlijk hebben we maar een klein deel van de functionaliteit van Hibernate gezien. De mogelijkheden zijn zeer breed en het is lange tijd een standaard industrietool geweest voor Java-ontwikkeling. Als je het in detail wilt bestuderen, kan ik het boek "Java Persistence API and Hibernate" aanbevelen. Ik besprak in een eerder artikel. Ik hoop dat dit artikel nuttig is geweest voor de lezers. Als je vragen hebt, stel ze dan in de comments. Ik zal graag antwoorden :) Vergeet ook niet de auteur in de wedstrijd te steunen door een "Vind ik leuk" te plaatsen. Of beter nog — "Love it" :) Veel succes met je studie!
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION