CodeGym /Java blog /Tilfældig /Din første Hibernate-applikation
John Squirrels
Niveau
San Francisco

Din første Hibernate-applikation

Udgivet i gruppen
I denne artikel vil du blive fortrolig med en af ​​de mest populære virksomhedsrammer til Java og oprette din første Hibernate-applikation. Aldrig hørt om Hibernate? Eller måske har du hørt om det, men ikke brugt det? Eller måske har du prøvet at bruge det, men det lykkedes ikke? I alle tre tilfælde - velkommen til under snittet :) Din første Hibernate-applikation - 1 Hej alle sammen! I denne artikel vil jeg tale om Hibernate-rammernes hovedfunktioner og hjælpe dig med at skrive din første mini-applikation. Til dette har vi brug for:
  1. IntelliJ IDEA Ultimate Edition
    Download den fra det officielle websted og aktiver 30-dages prøveversionen.
  2. PostgreSQL - et af de mest populære moderne databasestyringssystemer (DBMS)
  3. Maven (allerede tilsluttet IDEA)
  4. Lidt tålmodighed.
For en sikkerheds skyld postede jeg applikationskoden på GitHub (codegym-gren). Artiklen henvender sig primært til dem, der aldrig har arbejdet med denne teknologi før, så jeg har minimeret mængden af ​​kode. Lad os komme igang!

Hvad er Hibernate?

Det er en af ​​de mest populære implementeringer af objektrelationel mapping (ORM). En objektrelationel mapping definerer forholdet mellem softwareobjekter og databaseposter. Hibernate har selvfølgelig meget bred funktionalitet, men vi vil fokusere på de mest simple funktioner. Vores mål er at skabe en CRUD-applikation (Create, Read, Update, Delete), der vil være i stand til:
  1. Opret brugere (Bruger), søg efter dem i databasen efter ID, opdater deres data i databasen og slet dem fra databasen.
  2. Tildel bilobjekter (Auto) til brugere. Opret, opdater, find og slet biler fra databasen.
  3. Derudover bør applikationen automatisk fjerne "ejerløse" biler fra databasen. Med andre ord, når en bruger slettes, skal alle biler tilhørende denne bruger også slettes fra databasen.
Vores projekt vil være struktureret således: Din første Hibernate-applikation - 2Som du kan se, intet kompliceret. 6 klasser + 1 fil med konfigurationer. Først skal du oprette et nyt Maven-projekt i IntelliJ IDEA. Fil -> Nyt projekt. Vælg Maven blandt de foreslåede projekttyper og gå videre til næste trin. Din første Hibernate-applikation - 3Apache Maven er en ramme til automatisk opbygning af projekter baseret på en beskrivelse af deres struktur i POM-filer. Hele strukturen af ​​dit projekt vil blive beskrevet i pom.xml, en fil som IDEA selv vil oprette i roden af ​​dit projekt. I projektindstillingerne skal du angive følgende Maven-indstillinger: groupId og artifactId. I projekter er groupId normalt en beskrivelse af virksomheden eller forretningsenheden. Firmaets eller hjemmesidens domænenavn kan gå her. Til gengæld er artifactId navnet på projektet. For groupdId kan du indtaste com.yourNickname.codegym. Dette vil ikke have nogen effekt på applikationen. For artifactId skal du vælge et projektnavn, du kan lide. Udgaven kan forblive uændret. Din første Hibernate-applikation - 4På den sidste skærm skal du blot bekræfte de tidligere indtastede data.Din første Hibernate-applikation - 5Så vi har lavet projektet. Nu er der kun tilbage at skrive noget kode og få det til at virke :) Først og fremmest: Hvis vi vil lave en applikation, der fungerer med en database, kan vi bestemt ikke undvære en database! Download PostgreSQL herfra (jeg bruger version 9). PostgreSQL har en standardbruger 'postgres' — du skal finde et kodeord til det, når du installerer. Glem ikke adgangskoden. Vi får brug for det senere! (Generelt er det dårlig praksis at bruge standarddatabasen i applikationer, men vi vil gøre det for at reducere antallet af mavesår ved at oprette din egen database). Hvis du ikke er venner med kommandolinjen og SQL-forespørgsler, er der gode nyheder. IntelliJ IDEA giver en helt egnet brugergrænseflade til at arbejde med databasen. Din første Hibernate-applikation - 6(placeret i IDEAs højre rude, fanen Database). For at oprette en forbindelse skal du klikke på "+" og vælge vores datakilde (PostgeSQL). Udfyld felterne for brugeren og databasen ("postgres" for dem begge) og indtast adgangskoden, der blev sat under installationen af ​​PostgreSQL. Download om nødvendigt Postgres-driveren. Du kan gøre dette på samme side. Klik på "Test forbindelse" for at bekræfte, at databaseforbindelsen er etableret. Hvis du ser "Vellykket", så gå videre. Nu laver vi de tabeller, vi har brug for. Der vil være i alt to: brugere og biler. Parametre for brugertabellen: Din første Hibernate-applikation - 7Bemærk, at id er den primære nøgle. Hvis du ikke ved, hvad den primære nøgle er i SQL, så Google det. Dette er vigtigt. Indstillinger for autos tabel: Din første Hibernate-applikation - 8Til autos-tabellen skal du konfigurere en fremmednøgle. Det vil tjene til at forbinde vores borde. Jeg anbefaler, at du læser mere om det. Kort sagt refererer det til en ekstern tabel, i vores tilfælde brugere. Hvis en bil tilhører brugeren med id = 1, så vil feltet user_id for autos være lig med 1. Det er sådan, vi forbinder brugere med deres biler i vores applikation. I vores autos-tabel vil feltet user_id fungere som fremmednøgle. Det vil referere til id-feltet i brugertabellen. Din første Hibernate-applikation - 9Så vi har lavet en database med to tabeller. Hvad der er tilbage er at forstå, hvordan man administrerer det fra Java-kode. Vi starter med filen pom.xml, hvori vi skal inkludere de nødvendige biblioteker (i Maven kaldes de afhængigheder). Alle biblioteker er gemt i det centrale Maven-lager. De biblioteker, du angiver i pom.xml, er tilgængelige for dig at bruge i projektet. Din pom.xml skulle se sådan ud: Din første Hibernate-applikation - 10Intet kompliceret, som du kan se. Vi tilføjede kun 2 afhængigheder - til brug af PostgreSQL og Hibernate. Lad os nu gå videre til Java-koden. Opret alle de nødvendige pakker og klasser i projektet. For at starte har vi brug for en datamodel: klasserne Userog 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;
     }
 }
 
 
Som du kan se, har klasserne en masse obskure anmærkninger. Lad os begynde at grave i dem. For os er hovedannotationen @Entity. Læs om det på Wikipedia og lær det hele udenad. Dette er grundlaget for fonden. Denne anmærkning lader objekter i din Java-klasse blive kortlagt til en database. For at en klasse kan være en enhed, skal den opfylde følgende krav:
  • Det skal have en tom konstruktør ( publiceller protected)
  • Det kan ikke indlejres, en grænseflade eller enenum
  • Det kan ikke være finalog kan ikke have finalfelter/egenskaber
  • Den skal have mindst ét ​​@Id-felt.
Tjek dine entitetsklasser: de er meget populære steder at skyde dig selv i foden. Det er meget nemt at glemme noget. Desuden kan en enhed gøre følgende:
  • Det kan have ikke-tomme konstruktører
  • Det kan arve og gå i arv
  • Det kan have andre metoder og implementere grænseflader.
Som du kan se, Userligner klassen meget brugertabellen. Den har id, name, ogagefelter. Annoteringerne placeret over dem behøver ikke nogen særlig forklaring: det er tydeligt, at @Id angiver, at feltet er en identifikator for objekter af denne klasse. @Table-annotationen over klassen angiver navnet på den tabel, hvor objekterne er skrevet. Bemærk kommentaren over aldersfeltet: hvis navnet på feltet i klassen er det samme som navnet på tabellen, kan du udelade @Column-annotationen, og det vil virke. Hvad angår den del, der er angivet i klammeparenteserne ("strategi = GenerationType.IDENTITY"): der er flere strategier til at generere ID'er. Du kan Google dem, men for vores ansøgning behøver du ikke bekymre dig. Det vigtigste er, at værdien af ​​id for vores objekter genereres automatisk. Derfor er der ingen setter for id, og vi sætter det heller ikke i constructoren. Imidlertid,Userklasse skiller sig ud. Den har en liste over biler! Din første Hibernate-applikation - 11@OneToMany-annotationen hænger over listen. Det betyder, at flere biler kan svare til det samme objekt i brugerklassen. Elementet "mappedBy" henviser til klassens brugerfelt Auto. Biler og brugere hænger således sammen. OrphanRemoval-elementet angiver, om fjernelseshandlingen skal anvendes på enheder, der ikke længere har en relation. Hvis vi sletter en bruger fra databasen, så slettes også alle biler tilknyttet den. Til gengæld iAutoklasse, vil du se brugerfeltet med @ManyToOne-annotationen (en bruger kan svare til mange Autos) og @JoinColumn-annotationen. Det angiver, hvilken kolonne i autos-tabellen, der bruges til at referere til brugertabellen (dvs. den fremmednøgle, som vi talte om tidligere). Efter at have oprettet datamodellen, er det tid til at lære vores program at udføre operationer med dataene i databasen. Lad os starte med hjælpeklassen HibernateSessionFactoryUtil. Den har kun én opgave - at oprette en sessionsfabrik, så vores applikation kan arbejde med databasen (sig hej til Factory-designmønsteret!). Den ved ikke, hvordan man gør noget andet.

 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;
     }
 }
 
I denne klasse opretter vi et nyt konfigurationsobjekt og sender det de klasser, som det skal behandle som entiteter: Userog Auto. Vær opmærksom på configuration.getProperties()metoden. Hvilke andre ejendomme er der? Hvor kommer de fra? Egenskaber er dvaleindstillingerne angivet i den specielle hibernate.cfg.xml-fil. Din første Hibernate-applikation - 12Hibernate.cfg.xml kan læses her: new Configuration().configure(); Som du kan se, er der ikke noget særligt ved det: det indeholder parametrene for tilslutning til databasen, samt parameteren show_sql. Dette er påkrævet, så alle sql-forespørgsler udført af Hibernate vises på konsollen. På denne måde vil du se præcis, hvad Hibernate laver på ethvert givet tidspunkt, hvilket eliminerer enhver følelse af "magi". Dernæst skal vi brugeUserDAOklasse. Den bedste praksis er at programmere gennem grænsefladerne - opret en separat UserDAOgrænseflade og UserDAOImplimplementering, men jeg vil springe dette over for at reducere mængden af ​​kode. Gør ikke dette i rigtige projekter! DAO (data access object) designmønsteret er et af de mest almindelige. Ideen er enkel - opret et applikationslag, der kun er ansvarligt for at få adgang til data, intet mere. Hent data fra databasen, opdater data, slet data - det er det. Læs mere om DAO. Du vil konstant bruge dataadgangsobjekter i dit arbejde. Hvad kan vores UserDaoklasse? Som alle DAO'er kan det kun fungere med data. Find en bruger efter id, opdater dens data, slet den, få en liste over alle brugere fra databasen, eller gem en ny bruger i databasen - det er hele dens funktionalitet.

 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 metoder ligner hinanden. I de fleste af dem får vi et Session- objekt (databaseforbindelsessession) ved hjælp af vores Session Factory, opretter en enkelt transaktion i denne session, udfører de nødvendige datamanipulationer, gemmer resultatet af transaktionen i databasen og lukker derefter sessionen. Selve metoderne, som du kan se, er ret enkle. DAO er "hjertet" i vores ansøgning. Vi vil dog ikke oprette en DAO direkte og kalde dens metoder i vores main()metode. Al logik vil blive flyttet til UserServiceklassen.

 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);
     }
 
 
 }
 
 
En tjeneste er et applikationsdatalag, der er ansvarligt for at udføre forretningslogik. Hvis dit program skal udføre en form for forretningslogik, gør det det gennem tjenester. En tjeneste indeholder en UserDaoog kalder DAO-metoder i sine metoder. Det kan virke som om, vi duplikerer funktioner her (hvorfor ikke bare kalde metoderne fra et DAO-objekt?), men med masser af objekter og kompleks logik giver lagdeling af applikationen enorme fordele (det er god praksis - husk dette i fremtiden og læs om "applikationslag"). Vores service har enkel logik, men servicemetoder i projekter i den virkelige verden indeholder meget mere end én linje kode :) Nu har vi alt hvad du behøver for at køre applikationen! Lad os i main()metoden oprette en bruger og dens bil, associere den ene med den anden og gemme dem i databasen.

 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);
     }
 }
 
 
Som du kan se, har brugertabellen sin egen post, og biltabellen har sin egen post. Din første Hibernate-applikation - 13Din første Hibernate-applikation - 14Lad os prøve at omdøbe vores bruger. Ryd brugertabellen og udfør koden

 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);
     }
 }
 
 
Det virker! Din første Hibernate-applikation - 15Hvad hvis du sletter brugeren? Ryd brugertabellen (autos rydder sig selv) og udfør koden

 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);
     }
 }
 
 
Og vores borde er helt tomme (vær opmærksom på konsollen - alle anmodninger udført af Hibernate vil blive vist der). Du kan lege med applikationen og prøve alle dens funktioner. Opret f.eks. en bruger med biler, gem den i databasen, se på det id, der er tildelt brugeren, og prøv at bruge dette id imain()metode til at hente brugeren fra databasen og vise en liste over dens biler på konsollen. Vi har selvfølgelig kun set en lille del af Hibernates funktionalitet. Dets muligheder er meget brede, og det har længe været et standard industriværktøj til Java-udvikling. Hvis du vil studere det i detaljer, kan jeg anbefale bogen "Java Persistence API and Hibernate". Jeg anmeldte i en tidligere artikel. Jeg håber, at denne artikel har været nyttig for læserne. Hvis du har spørgsmål, så spørg dem i kommentarerne. Jeg svarer gerne :) Glem heller ikke at støtte forfatteren i konkurrencen ved at skrive et "Synes godt om". Eller endnu bedre — "Love it" :) Held og lykke med dine studier!
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION