CodeGym /Java blog /Véletlen /Az első hibernált alkalmazás
John Squirrels
Szint
San Francisco

Az első hibernált alkalmazás

Megjelent a csoportban
Ebben a cikkben megismerkedhet az egyik legnépszerűbb Java vállalati keretrendszerrel, és elkészítheti első Hibernate alkalmazását. Soha nem hallottál a Hibernate-ról? Vagy esetleg hallott már róla, de még nem használta? Vagy esetleg megpróbáltad használni, de nem sikerült? Mindhárom esetben - üdvözöllek a vágás alatt :) Az első hibernált alkalmazás – 1 Hello mindenkinek! Ebben a cikkben a Hibernate keretrendszer főbb funkcióiról fogok beszélni, és segítek megírni az első minialkalmazást. Ehhez szükségünk van:
  1. IntelliJ IDEA Ultimate Edition
    Töltse le a hivatalos webhelyről , és aktiválja a 30 napos próbaverziót.
  2. PostgreSQL – az egyik legnépszerűbb modern adatbázis-kezelő rendszer (DBMS)
  3. Maven (már be van kötve az IDEA-val)
  4. Egy kis türelem.
Minden esetre közzétettem az alkalmazás kódját a GitHubon ( codegym ág). A cikk elsősorban azoknak szól, akik még soha nem dolgoztak ezzel a technológiával, ezért minimálisra csökkentettem a kód mennyiségét. Kezdjük el!

Mi az a hibernált állapot?

Ez az egyik legnépszerűbb objektum-relációs leképezés (ORM) megvalósítás. Az objektum-relációs leképezés a szoftverobjektumok és az adatbázisrekordok közötti kapcsolatot határozza meg. Természetesen a Hibernate nagyon széles funkcionalitással rendelkezik, de mi a legegyszerűbb funkciókra fogunk összpontosítani. Célunk egy olyan CRUD (Create, Read, Update, Delete) alkalmazás létrehozása, amely képes lesz:
  1. Hozzon létre felhasználókat (User), keresse meg őket azonosító alapján az adatbázisban, frissítse adataikat az adatbázisban, és törölje őket az adatbázisból.
  2. Rendeljen autóobjektumokat (Automatikus) a felhasználókhoz. Hozzon létre, frissítsen, keressen és töröljön autókat az adatbázisból.
  3. Ezenkívül az alkalmazásnak automatikusan eltávolítania kell a "tulajdonos nélküli" autókat az adatbázisból. Más szóval, egy felhasználó törlésekor az adott felhasználóhoz tartozó összes autót is törölni kell az adatbázisból.
Projektünk a következőképpen épül fel: Az első hibernált alkalmazás – 2Mint látható, semmi bonyolult. 6 osztály + 1 fájl konfigurációkkal. Először hozzon létre egy új Maven-projektet az IntelliJ IDEA-ban. Fájl -> Új projekt. Válassza ki a Maven-t a javasolt projekttípusok közül, és lépjen a következő lépésre. Az első hibernált alkalmazás – 3Az Apache Maven egy keretrendszer a projektek automatikus felépítésére a POM-fájlokban lévő szerkezetük leírása alapján. A projekt teljes szerkezete a pom.xml fájlban lesz leírva, egy olyan fájlban, amelyet maga az IDEA fog létrehozni a projekt gyökerében. A projektbeállításokban a következő Maven beállításokat kell megadnia: groupId és artifactId. A projektekben a groupId általában a vállalat vagy az üzleti egység leírása. Ide kerülhet a cég vagy webhely domain neve. Az artifactId viszont a projekt neve. A groupdId mezőben megadhatja a következőt com.yourNickname.codegym: Ennek nincs hatása az alkalmazásra. Az artifactId-hez válassza ki a kívánt projektnevet. A változat változatlanul hagyható. Az első hibernált alkalmazás – 4Az utolsó képernyőn egyszerűen erősítse meg az előzőleg megadott adatokat.Az első hibernált alkalmazás – 5Tehát létrehoztuk a projektet. Most már nincs más hátra, mint írni egy kódot és működőképessé tenni :) Először is: ha olyan alkalmazást akarunk létrehozni, ami adatbázissal működik, akkor biztosan nem nélkülözhetjük adatbázist! Töltse le innen a PostgreSQL-t ( 9-es verziót használok). A PostgreSQL alapértelmezett "postgres" felhasználóval rendelkezik – telepítéskor ki kell találnia egy jelszót. Ne felejtse el a jelszót. Később szükségünk lesz rá! (Általában az alapértelmezett adatbázis használata az alkalmazásokban rossz gyakorlat, de megtesszük, hogy saját adatbázis létrehozásával csökkentsük a fekélyek számát). Ha nem ismeri a parancssort és az SQL-lekérdezéseket, akkor van egy jó hír. Az IntelliJ IDEA teljesen megfelelő felhasználói felületet biztosít az adatbázissal való munkához. Az első hibernált alkalmazás – 6(az IDEA jobb oldali ablaktábláján, az Adatbázis lapon található). Kapcsolat létrehozásához kattintson a "+" gombra, és válassza ki az adatforrásunkat (PostgeSQL). Töltse ki a felhasználó és az adatbázis mezőit („postgres” mindkettőnél), és adja meg a PostgreSQL telepítése során beállított jelszót. Ha szükséges, töltse le a Postgres illesztőprogramot. Ezt megteheti ugyanazon az oldalon. Kattintson a "Kapcsolat tesztelése" gombra az adatbázis-kapcsolat létrejöttének ellenőrzéséhez. Ha a "Sikeres" üzenetet látja, lépjen tovább. Most elkészítjük a szükséges táblázatokat. Összesen kettő lesz: felhasználók és autók. A felhasználók tábla paraméterei: Az első hibernált alkalmazás – 7Vegye figyelembe, hogy az id az elsődleges kulcs. Ha nem tudja, mi az elsődleges kulcs az SQL-ben, keresse meg a Google-on. Ez fontos. Az Autos táblázat beállításai: Az első hibernált alkalmazás – 8Az autos táblához egy idegen kulcsot kell beállítani. Táblázataink összekapcsolására szolgál majd. Azt javaslom, hogy olvasson róla többet. Leegyszerűsítve egy külső táblára hivatkozik, esetünkben a felhasználókra. Ha egy autó az id = 1 felhasználóhoz tartozik, akkor az autos user_id mezője 1 lesz. Alkalmazásunkban így társítjuk a felhasználókat az autóikhoz. Az autos táblánkban a user_id mező idegen kulcsként fog működni. A felhasználók tábla id mezőjére fog hivatkozni. Az első hibernált alkalmazás – 9Tehát létrehoztunk egy adatbázist két táblával. Továbbra is meg kell értenünk, hogyan kezelhetjük ezt Java kódból. Kezdjük a pom.xml fájllal, amelybe bele kell foglalnunk a szükséges könyvtárakat (a Mavenben ezeket függőségeknek nevezzük). Az összes könyvtár a központi Maven adattárban van tárolva. A pom.xml fájlban megadott könyvtárak használhatók a projektben. A pom.xml fájlnak így kell kinéznie: Az első hibernált alkalmazás – 10Semmi bonyolult, mint láthatja. Csak 2 függőséget adtunk hozzá – a PostgreSQL és a Hibernate használatához. Most térjünk át a Java kódra. Hozzon létre minden szükséges csomagot és osztályt a projektben. Kezdéshez adatmodellre van szükségünk: a Userés Autoosztályokra.

 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;
     }
 }
 
 
Amint láthatja, az osztályok egy csomó homályos megjegyzést tartalmaznak. Kezdjünk el ásni őket. Számunkra a fő megjegyzés az @Entity. Olvass róla a Wikipédián, és tanuld meg fejből. Ez az alapítvány alapja. Ez az annotáció lehetővé teszi, hogy a Java osztály objektumai adatbázishoz legyenek leképezve. Ahhoz, hogy egy osztály entitás legyen, meg kell felelnie a következő követelményeknek:
  • Üres konstruktornak kell lennie ( publicvagy protected)
  • Nem lehet beágyazott, interfész vagy anenum
  • Nem lehetnek finalés nem lehetnek finalmezői/tulajdonságai
  • Legalább egy @Id mezővel kell rendelkeznie.
Ellenőrizze az entitásosztályait: nagyon népszerű helyek, ahol lábon lőheti magát. Nagyon könnyű elfelejteni valamit. Ezenkívül egy entitás a következőket teheti:
  • Lehetnek benne nem üres konstruktorok
  • Örökölhet és örökölhető
  • Más módszerekkel és interfészekkel is rendelkezhet.
Mint látható, az Userosztály nagyon hasonlít a felhasználók táblájához. Van benne id, name, ésagemezőket. A felettük található megjegyzések nem igényelnek különösebb magyarázatot: egyértelmű, hogy az @Id azt jelzi, hogy a mező az ebbe az osztályba tartozó objektumok azonosítója. Az osztály feletti @Table megjegyzés jelzi annak a táblának a nevét, amelybe az objektumokat írják. Jegyezze meg az életkor mező feletti megjegyzést: ha az osztályban a mező neve megegyezik a táblázat nevével, akkor kihagyhatja a @Column megjegyzést, és működni fog. Ami a kapcsos zárójelben jelzett részt illeti ("stratégia = GenerationType.IDENTITY"): többféle stratégia létezik az azonosítók generálására. Használhatja őket a Google-on, de a mi alkalmazásunkhoz nem kell vesződnie. A lényeg az, hogy objektumainknál az id értéke automatikusan generálódik. Ennek megfelelően az id-re nincs setter, és a konstruktorban sem állítjuk be. Azonban,Userosztály kiemelkedik. Van egy autólista! Az első hibernált alkalmazás – 11A @OneToMany kommentár a lista felett lóg. Ez azt jelenti, hogy a User osztály ugyanazon objektumának több autó is megfelelhet. A "mappedBy" elem az osztály felhasználói mezőjére utal Auto. Így az autók és a felhasználók kapcsolatban állnak egymással. Az orphanRemoval elem jelzi, hogy alkalmazni kell-e az eltávolítási műveletet olyan entitásokra, amelyeknek már nincs kapcsolatuk. Ha törölünk egy felhasználót az adatbázisból, akkor az összes hozzá tartozó autó is törlődik. Viszont aAutoosztályban, látni fogja a felhasználói mezőt a @ManyToOne annotációval (egy felhasználó több autónak is megfelelhet) és a @JoinColumn megjegyzéssel. Azt jelzi, hogy az autos tábla melyik oszlopa hivatkozik a felhasználók táblájára (azaz az idegen kulcsra, amelyről korábban beszéltünk). Az adatmodell elkészítése után itt az ideje, hogy megtanítsuk programunkat az adatbázisban lévő adatokkal műveletek végrehajtására. Kezdjük a HibernateSessionFactoryUtil segédprogrammal. Csak egy feladata van – létrehozni egy munkamenet-gyárat az alkalmazásunk számára, hogy együttműködjön az adatbázissal (köszönjön a Factory tervezési mintájának!). Nem tudja, hogyan csináljon mást.

 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;
     }
 }
 
Ebben az osztályban létrehozunk egy új konfigurációs objektumot, és átadjuk neki azokat az osztályokat, amelyeket entitásként kell kezelnie: Userés Auto. Ügyeljen a configuration.getProperties()módszerre. Milyen egyéb tulajdonságok vannak? Honnan jöttetek? A tulajdonságok a speciális hibernate.cfg.xml fájlban feltüntetett hibernálási beállítások. Az első hibernált alkalmazás – 12Itt olvasható a Hibernate.cfg.xml: new Configuration().configure(); Amint látja, nincs benne semmi különösebb: tartalmazza az adatbázishoz való csatlakozás paramétereit, valamint a show_sql paramétert. Erre azért van szükség, hogy a Hibernate által végrehajtott összes sql-lekérdezés megjelenjen a konzolon. Így pontosan láthatja, mit csinál a Hibernate az adott pillanatban, és kiküszöböli a "varázslat" érzését. Ezután szükségünk van aUserDAOosztály. A legjobb gyakorlat az interfészeken keresztül történő programozás – külön UserDAOfelület létrehozása és UserDAOImplmegvalósítása, de ezt kihagyom a kód mennyiségének csökkentése érdekében. Ne csináld ezt valódi projektekben! A DAO (adatelérési objektum) tervezési minta az egyik leggyakoribb. Az ötlet egyszerű – hozzon létre egy alkalmazási réteget, amely csak az adatok eléréséért felelős, semmi több. Adatok lekérése az adatbázisból, adatok frissítése, adatok törlése – ennyi. Tanulj többet a DAO-ról. Munkájában folyamatosan adatelérési objektumokat fog használni. Mit tehet az UserDaoosztályunk? Nos, mint minden DAO, ez is csak adatokkal tud működni. Keressen egy felhasználót azonosító alapján, frissítse az adatait, törölje azokat, kérje le az összes felhasználó listáját az adatbázisból, vagy mentsen el egy új felhasználót az adatbázisban – ez a teljes funkciója.

 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;
     }
 }
 
UserDaomódszerei hasonlóak egymáshoz. Legtöbbjükben Session Factoryunk segítségével kapunk egy Session objektumot (adatbázis-kapcsolati munkamenetet), ezen belül egyetlen tranzakciót hozunk létre, elvégezzük a szükséges adatkezeléseket, elmentjük a tranzakció eredményét az adatbázisba, majd lezárjuk a munkamenetet. Maguk a módszerek, mint láthatja, meglehetősen egyszerűek. A DAO az alkalmazásunk "szíve". Azonban nem fogunk közvetlenül létrehozni egy DAO-t, és nem hívjuk meg a metódusait a módszerünkben main(). Minden logika átkerül az UserServiceosztályba.

 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 szolgáltatás egy alkalmazás adatréteg, amely az üzleti logika végrehajtásáért felelős. Ha a programnak valamilyen üzleti logikát kell végrehajtania, akkor azt szolgáltatásokon keresztül teszi. Egy szolgáltatás a-t tartalmaz UserDao, és metódusaiban DAO metódusokat hív meg. Úgy tűnhet, hogy itt függvényeket duplikálunk (miért nem csak egy DAO objektumból hívjuk meg a metódusokat?), de sok objektummal és összetett logikával az alkalmazás rétegezése óriási előnyökkel jár (ez jó gyakorlat – ne feledje ezt a jövőben) és olvassa el az "alkalmazási rétegekről"). Szolgáltatásunk egyszerű logikával rendelkezik, de a valós projektek szolgáltatási metódusai sokkal több kódsort tartalmaznak :) Most már mindent megtalálunk, ami az alkalmazás futtatásához szükséges! A main()metódusban hozzunk létre egy felhasználót és annak autóját, társítsuk egyiket a másikhoz, és mentsük el az adatbázisba.

 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);
     }
 }
 
 
Mint látható, a felhasználók táblának saját rekordja van, az autos táblának pedig saját rekordja. Az első hibernált alkalmazás – 13Az első hibernált alkalmazás – 14Próbáljuk meg átnevezni a felhasználónkat. Törölje a felhasználók tábláját, és futtassa a kódot

 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);
     }
 }
 
 
Működik! Az első hibernált alkalmazás – 15Mi van, ha törli a felhasználót? Törölje a felhasználók tábláját (az autos törli magát), és futtassa a kódot

 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);
     }
 }
 
 
És a táblázataink teljesen üresek (figyeljen a konzolra - a Hibernate által végrehajtott összes kérés megjelenik ott). Az alkalmazással játszhatsz, és minden funkcióját kipróbálhatod. Például hozzon létre egy felhasználót autókkal, mentse el az adatbázisba, nézze meg a felhasználóhoz rendelt azonosítót, és próbálja meg ezt az azonosítót használni amain()módszerrel lekérheti a felhasználót az adatbázisból, és megjelenítheti az autóinak listáját a konzolon. Természetesen a Hibernate funkcióinak csak egy kis részét láttuk. Lehetőségei nagyon szélesek, és régóta szabványos iparági eszköz a Java fejlesztéshez. Ha szeretnéd részletesebben tanulmányozni, ajánlom a "Java Persistence API and Hibernate" című könyvet. Egy korábbi cikkben áttekintettem. Remélem, hogy ez a cikk hasznos volt az olvasóknak. Ha kérdése van, tegye fel őket a megjegyzésekben. Szívesen válaszolok :) Valamint ne felejtsd el támogatni a szerzőt a pályázatban egy "Tetszik" feladásával. Vagy még jobb: "Imádom" :) Sok sikert a tanuláshoz!
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION