JavaRush /Java Blog /Random-TL /Ang iyong unang Hibernate application

Ang iyong unang Hibernate application

Nai-publish sa grupo
Sa artikulong ito, makikilala mo ang isa sa pinakasikat na enterprise framework para sa Java at gagawa ng iyong unang application gamit ang Hibernate. Hindi kailanman narinig ang tungkol sa Hibernate? Marahil ay narinig mo na ang tungkol dito, ngunit hindi mo pa ito ginagamit? O sinubukang magsimula, ngunit hindi nagtagumpay? Sa lahat ng tatlong kaso, maligayang pagdating sa cut :) Ang iyong unang Hibernate application - 1Kumusta sa lahat! Sa artikulong ito, pag-uusapan ko ang tungkol sa mga pangunahing tampok ng balangkas ng Hibernate at tutulungan kang isulat ang iyong unang mini-application. Para dito kailangan namin:
  1. Intellij Idea Ultimate Edition;
    Mag-download mula sa opisyal na website at i-activate ang 30-araw na bersyon ng pagsubok.
  2. Ang PostgeSQL ay isa sa pinakasikat na modernong database management system (DBMS);
  3. Maven (na-built na sa IDEA);
  4. Konting pasensya.
Ang artikulo ay pangunahing nakatuon sa mga taong hindi pa nakatrabaho sa teknolohiyang ito, kaya ang halaga ng code ay nabawasan hangga't maaari. Magsimula na tayo!

Ano ang Hibernate?

Isa ito sa pinakasikat na pagpapatupad ng modelong ORM. Ang object-relational model ay naglalarawan ng mga ugnayan sa pagitan ng mga software object at mga tala sa database. Siyempre, napakalawak ng functionality ng Hibernate, ngunit tututuon natin ang mga pinakasimpleng function. Ang aming layunin: lumikha ng CRUD application (Gumawa, Magbasa, Mag-update, Magtanggal) na magagawang:
  1. Lumikha ng mga user (User), pati na rin ang paghahanap para sa kanila sa database sa pamamagitan ng ID, i-update ang kanilang data sa database, at tanggalin din sila mula sa database.
  2. Magtalaga ng mga bagay ng sasakyan (Auto) sa mga user. Lumikha, mag-edit, maghanap at magtanggal ng mga kotse mula sa database.
  3. Bilang karagdagan, ang application ay dapat na awtomatikong alisin ang "ulila" na mga kotse mula sa database. Yung. Kapag na-delete ang isang user, dapat ding tanggalin sa database ang lahat ng sasakyang pagmamay-ari niya.
Ang istraktura ng aming proyekto ay ang mga sumusunod: Ang iyong unang Hibernate application - 2Tulad ng nakikita mo, walang kumplikado. 6 na klase + 1 file na may mga config. Una, gumawa tayo ng bagong maven project sa Intellij Idea. File -> Bagong Proyekto. Mula sa mga iminungkahing uri ng proyekto, piliin ang Maven at magpatuloy. Ang iyong unang Hibernate application - 3Ang Apache Maven ay isang balangkas para sa pag-automate ng pagpupulong ng mga proyekto batay sa isang paglalarawan ng kanilang istraktura sa mga file sa wikang POM. Ang buong istraktura ng iyong proyekto ay ilalarawan sa pom.xml file, na mismong IDEA ang gagawa sa ugat ng iyong proyekto. Sa mga setting ng proyekto kakailanganin mong tukuyin ang mga parameter ng Maven - groupId at artifactId. Karaniwan sa mga proyekto ang groupId ay ang pangalan ng organisasyon o dibisyon, at ang domain name ng organisasyon o site ng proyekto ay nakasulat doon. Sa turn, artifactId ang pangalan ng proyekto. Para sa groupdId maaari mong tukuyin com.вашНикнейм.javarush, hindi ito makakaapekto sa pagpapatakbo ng application sa anumang paraan. Para sa artifactId, pumili ng anumang pangalan ng proyekto na gusto mo. Maaari mo ring iwanan ang Bersyon na hindi nagbabago. Ang iyong unang Hibernate application - 4Sa huling screen, kumpirmahin lang ang dati mong inilagay na data. Ang iyong unang Hibernate application - 5Kaya, nilikha namin ang proyekto, ang natitira ay isulat ang code at gawin itong gumana :) Una sa lahat, kung gusto naming lumikha ng isang application na gumagana sa isang database, tiyak na hindi namin magagawa nang walang database! I-download ang PostgreSQL mula dito (Gumagamit ako ng bersyon 9). Ang PostgreSQL ay may default na user na 'postgres', kakailanganin mong lumikha ng isang password para dito sa panahon ng pag-install. Huwag kalimutan ang iyong password, kakailanganin namin ito mamaya! (Sa pangkalahatan, ang paggamit ng default na database sa mga application ay masamang kasanayan, ngunit upang mabawasan ang dami ng almoranas, gagawin namin ang paggawa ng aming sariling database). Kung hindi ka komportable sa command line at SQL query, may magandang balita. Nagbibigay ang Intellij IDEA ng medyo angkop na user interface para sa pagtatrabaho sa database. Mukhang ganito: Ang iyong unang Hibernate application - 6(matatagpuan sa kanang sidebar ng IDEA, Database tab) Upang gumawa ng koneksyon, i-click ang “+”, piliin ang aming provider (PostgeSQL). Punan ang mga patlang ng gumagamit, pangalan ng database (parehong mga postgres) at ipasok ang password na itinakda mo kapag nag-i-install ng PostgreSQL. Kung kinakailangan, i-download ang driver ng Postgres, maaari itong gawin sa parehong pahinang ito. I-click ang "Subukan ang Koneksyon" upang suriin na ang koneksyon sa database ay naitatag. Kung nakita mo ang inskripsyon na "Matagumpay", nagpapatuloy kami. Ngayon gawin natin ang mga talahanayan na kailangan natin. Magkakaroon ng dalawa sa kanila - mga gumagamit at mga sasakyan. Mga parameter para sa talahanayan ng mga user: Ang iyong unang aplikasyon sa Hibernate - 7Pakitandaan na ang id ang pangunahing key. Kung hindi mo alam kung ano ang pangunahing key sa SQL, i-Google ito, mahalaga ito. Setting para sa autos table: Ang iyong unang aplikasyon sa Hibernate - 8Para sa mga auto kailangan mong i-configure ang Foreign Key - foreign key. Ito ay mag-uugnay sa aming mga talahanayan. Pinapayuhan ko kayong magbasa nang higit pa tungkol sa kanya; Upang ilagay ito nang napakasimple, ito ay tumutukoy sa isang panlabas na talahanayan, sa aming kaso, mga gumagamit. Kung ang kotse ay pagmamay-ari ng isang user na may id=1, pagkatapos ay sa user_id field ng autos table magkakaroon ito ng 1. Ito ay kung paano namin ikinonekta ang mga user sa kanilang mga sasakyan sa aming application. Sa aming talahanayan ng autos, ang field ng user_id ay magsisilbing foreign key. Magre-refer ito sa field ng id ng talahanayan ng mga user. Ang iyong unang Hibernate application - 9Kaya, lumikha kami ng isang database na may dalawang talahanayan. Ito ay nananatiling maunawaan kung paano pamahalaan ito mula sa Java code. Magsisimula tayo sa pom.xml file, kung saan kailangan nating isama ang mga kinakailangang aklatan (sa wikang Maven ay tinatawag silang mga dependency). Ang lahat ng mga aklatan ay naka-imbak sa central Maven repository. Yaong sa kanila na iyong tinukoy sa pom.xml, maaari mong gamitin sa proyekto. Dapat ganito ang hitsura ng iyong pom.xml: Ang iyong unang Hibernate application - 10Walang kumplikado gaya ng nakikita mo. Nagdagdag lang kami ng 2 dependencies - para sa paggamit ng PostgreSQL at Hibernate. Ngayon ay lumipat tayo sa Java code. Lumikha ng lahat ng kinakailangang mga pakete at klase para sa proyekto. Upang magsimula, kakailanganin namin ang mga modelo ng data - mga klase Userat 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 not specify Column name if it matches the name of the column 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 not specify Column name if it matches the name of the column 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;
    }
}
Tulad ng nakikita mo, ang mga klase ay nilagyan ng isang grupo ng hindi pa rin malinaw na mga anotasyon. Simulan natin ang pakikitungo sa kanila. Ang pangunahing anotasyon para sa amin ay @Entity. Basahin ang tungkol dito sa Wikipedia at tandaan ang lahat, ito ang batayan ng mga pangunahing kaalaman. Ang anotasyong ito ay nagbibigay-daan sa mga Java object ng iyong klase na maiugnay sa database. Para maging entity ang isang klase, dapat itong matugunan ang mga sumusunod na kinakailangan:
  • Dapat ay may walang laman na constructor ( publico protected);
  • Hindi maaaring nested, interface o enum;
  • Hindi maaaring finalat hindi maaaring maglaman ng final-fields/properties;
  • Dapat maglaman ng kahit isang field ng @Id.
Suriin ang iyong mga klase sa entity, ito ay isang napakasikat na lugar para kunan ang iyong sarili sa paa. Napakadaling kalimutan ang isang bagay. Sa kasong ito, ang entity ay maaaring:
  • Naglalaman ng mga hindi walang laman na konstruktor;
  • Mamana at mamana;
  • Maglaman ng iba pang mga pamamaraan at ipatupad ang mga interface.
Tulad ng nakikita mo, ang klase Useray halos kapareho sa talahanayan ng mga gumagamit. May mga patlang id, name, age. Ang mga anotasyon na matatagpuan sa itaas ng mga ito ay hindi nangangailangan ng maraming paliwanag: malinaw na ang @Id ay isang indikasyon na ang field ay isang identifier ng mga bagay ng klase na ito. Ang @Table annotation sa itaas ng klase ay tumutukoy sa pangalan ng talahanayan kung saan nakasulat ang mga bagay. Bigyang-pansin ang komento sa itaas ng field ng edad: kung magkapareho ang pangalan ng field sa klase at talahanayan, hindi mo kailangang idagdag ang @Column annotation, gagana ito nang ganoon. Tungkol sa "diskarte = GenerationType.IDENTITY" na nakasaad sa panaklong: mayroong ilang mga diskarte sa pagbuo ng ID. Maaari mo itong i-google, ngunit sa loob ng balangkas ng aming aplikasyon hindi mo kailangang mag-abala. Ang pangunahing bagay ay ang mga id para sa aming mga bagay ay awtomatikong mabubuo, kaya walang setter para sa id, at hindi rin namin ito tinukoy sa konstruktor. UserGayunpaman, namumukod-tangi pa rin ang klase sa ilang paraan . May listahan siya ng mga sasakyan! Ang @OneToMany annotation ay lilitaw sa itaas ng listahan. Nangangahulugan ito na ang isang bagay ng klase ng gumagamit ay maaaring tumutugma sa ilang mga makina. Ang setting na "mappedBY" ay tumuturo sa field ng user ng klase Auto. Sa ganitong paraan, ang mga makina at user ay konektado sa isa't isa. Ang setting ng orphanRemoval ay nagsasalin nang maayos mula sa English - "alisin ang mga ulila". Kung tatanggalin namin ang isang user mula sa database, ang lahat ng mga kotse na nauugnay sa kanya ay tatanggalin din. Sa kabilang banda, sa klase Automakikita mo ang field ng user na may @ManyToOne annotation (maraming Autos ang maaaring tumugma sa isang User) at ang @JoinColumn annotation. Ito ay nagpapahiwatig sa pamamagitan ng kung aling column sa autos table ang koneksyon sa mga user table ay nangyayari (ang parehong dayuhang key na napag-usapan natin kanina). Pagkatapos gumawa ng modelo ng data, oras na para turuan ang aming programa na magsagawa ng mga operasyon sa data na ito sa database. Magsimula tayo sa klase ng utility na HibernateSessionFactoryUtil. Mayroon lamang itong isang gawain - upang lumikha ng isang pabrika ng session para sa aming aplikasyon upang gumana sa database (hello, ang pattern na "Pabrika!"). Wala na siyang magagawa pa.
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;
    }
}
Sa klase na ito, gumawa kami ng bagong configuration object, Configuration, at ipapasa dito ang mga klase na dapat maisip nito bilang mga entity - Userat Auto. Bigyang-pansin ang pamamaraan configuration.getProperties(). Ano ang iba pang mga katangian? saan? Ang mga katangian ay mga parameter para sa kung paano gumagana ang hibernate, na tinukoy sa isang espesyal na file hibernate.cfg.xml. Ang iyong unang Hibernate application - 11Ang Hibernate.cfg.xml ay binasa dito: new Configuration().configure(); Tulad ng nakikita mo, walang espesyal dito - mga parameter para sa pagkonekta sa database, at isang espesyal na parameter na show_sql. Ito ay kinakailangan upang ang lahat ng SQL query na hibernate ay isasagawa laban sa aming database ay output sa console. Sa ganitong paraan, makikita mo nang eksakto kung ano ang ginagawa ng Hibernate sa bawat sandali at mapupuksa ang "magic" na epekto. Susunod na kailangan namin ang klase UserDAO. (Sa mabuting paraan, kailangan mong mag-program sa pamamagitan ng mga interface - lumikha ng isang interface UserDAOat hiwalay na ipatupad ito UserDAOImpl, ngunit upang mabawasan ang dami ng code ay aalisin ko ito. Huwag gawin ito sa mga totoong proyekto!). Ang DAO (data access object) ay isa sa mga pinakakaraniwang pattern ng disenyo, "Data Access". Ang kahulugan nito ay simple - upang lumikha ng isang layer sa application na responsable lamang para sa pag-access ng data, at wala nang iba pa. Kumuha ng data mula sa database, i-update ang data, tanggalin ang data - at iyon na. Magbasa nang higit pa tungkol sa mga DAO; palagi mong gagamitin ang mga ito sa iyong trabaho. Ano ang magagawa ng aming klase UserDao? Sa totoo lang, tulad ng lahat ng DAO, maaari lamang itong gumana sa data. Maghanap ng user sa pamamagitan ng id, i-update ang kanyang data, tanggalin siya, ilabas ang listahan ng lahat ng user mula sa database o i-save ang bagong user sa database - iyon lang ang functionality nito.
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;
    }
}
Ang mga pamamaraan UserDaoay magkatulad sa bawat isa. Sa karamihan ng mga ito, nakakatanggap kami ng object ng Session (isang session na kumokonekta sa aming database) gamit ang aming Session Factory, lumikha ng isang transaksyon sa loob ng session na ito, isagawa ang mga kinakailangang pagbabago sa data, i-save ang resulta ng transaksyon sa database at isara ang session. Ang mga pamamaraan mismo, tulad ng nakikita mo, ay medyo simple. Ang DAO ay ang "puso" ng aming aplikasyon. Gayunpaman, hindi kami direktang lilikha ng DAO at tatawagin ang mga pamamaraan nito sa aming main(). Ang lahat ng lohika ay ililipat sa 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);
    }


}
Ang serbisyo ay isang layer ng data sa application na responsable para sa pagpapatupad ng lohika ng negosyo. Kung ang iyong programa ay kailangang magsagawa ng ilang lohika ng negosyo, ginagawa ito sa pamamagitan ng mga serbisyo. Naglalaman ang serbisyo sa loob mismo UserDaoat tinatawag ang mga pamamaraan ng DAO sa mga pamamaraan nito. Ito ay maaaring mukhang tulad ng pagdoble ng mga pag-andar para sa iyo (bakit hindi na lang tumawag ng mga pamamaraan mula sa isang bagay na dao), ngunit sa isang malaking bilang ng mga bagay at kumplikadong lohika, ang paghiwa-hiwalay ng application sa mga layer ay may malaking benepisyo (ito ay magandang kasanayan, tandaan ang impormasyong ito para sa hinaharap at basahin ang tungkol sa "mga layer ng application" "). Sa aming serbisyo, ang lohika ay simple, ngunit sa mga totoong proyekto, ang mga pamamaraan ng serbisyo ay maglalaman ng higit sa isang linya ng code :) Ngayon ay mayroon na kaming lahat ng kailangan namin para gumana ang application! Gumawa tayo main()ng isang user at mga makina para sa kanya sa pamamaraan, ikonekta ang mga ito sa isa't isa at i-save ang mga ito sa database.
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("Masha",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);
    }
}
Tulad ng nakikita mo, ang talahanayan ng mga gumagamit ay may sariling entry, at ang talahanayan ng autos ay may sarili nitong entry. Ang iyong unang Hibernate application - 13Ang iyong unang Hibernate application - 14Subukan nating palitan ang pangalan ng ating user. I-clear natin ang talahanayan ng mga user at patakbuhin ang code
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("Masha",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("Sasha");
        userService.updateUser(user);
    }
}
Gumagana! Ang iyong unang Hibernate application - 15Paano kung magtanggal ka ng user? I-clear natin ang talahanayan ng mga user (ma-clear ng autos ang sarili nito) at i-execute ang code
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("Masha",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("Sasha");
        userService.updateUser(user);
        userService.deleteUser(user);
    }
}
At ang aming mga talahanayan ay ganap na walang laman (pansinin ang console, lahat ng mga query na naisakatuparan ng Hibernate ay ipapakita doon). Maaari kang makipaglaro sa application at subukan ang lahat ng mga tampok nito. Halimbawa, lumikha ng isang user na may mga machine, i-save ito sa database, tingnan kung anong ID ang itinalaga dito, at subukang gamitin ang paraan main()upang "hilahin" ang user mula sa database gamit ang id na ito at magpakita ng listahan ng kanyang mga machine sa console . Siyempre, nakita lang namin ang isang maliit na bahagi ng functionality ng Hibernate. Napakalawak ng mga kakayahan nito, at matagal na itong isa sa mga pamantayan sa industriya para sa pagpapaunlad ng Java. Kung nais mong pag-aralan ito nang detalyado, maaari kong irekomenda ang aklat na "Java Persistence API at Hibernate", na sinuri ko sa isa sa aking mga nakaraang artikulo. Umaasa ako na ang artikulong ito ay naging kapaki-pakinabang sa mga mambabasa. Kung mayroon kang anumang mga katanungan, tanungin sila sa mga komento, ikalulugod kong sagutin :) Gayundin, huwag kalimutang suportahan ang may-akda sa kumpetisyon sa pamamagitan ng "I-like" siya. Or better yet - “I like it very much” :) Good luck sa iyong pag-aaral!
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION