JavaRush /Blog Java /Random-MS /Aplikasi Hibernate pertama anda

Aplikasi Hibernate pertama anda

Diterbitkan dalam kumpulan
Dalam artikel ini, anda akan berkenalan dengan salah satu rangka kerja perusahaan yang paling popular untuk Java dan mencipta aplikasi pertama anda menggunakan Hibernate. Tidak pernah mendengar tentang Hibernate? Mungkin anda pernah mendengar tentangnya, tetapi tidak menggunakannya? Atau cuba bermula, tetapi tidak berjaya? Dalam ketiga-tiga kes, selamat datang ke pemotongan :) Aplikasi Hibernate pertama anda - 1Hello semua! Dalam artikel ini, saya akan bercakap tentang ciri utama rangka kerja Hibernate dan membantu anda menulis aplikasi mini pertama anda. Untuk ini kita perlukan:
  1. Intellij Idea Ultimate Edition;
    Muat turun dari tapak web rasmi dan aktifkan versi percubaan 30 hari.
  2. PostgeSQL ialah salah satu sistem pengurusan pangkalan data moden (DBMS);
  3. Maven (sudah terbina dalam IDEA);
  4. Sabar sikit.
Artikel ini ditujukan terutamanya kepada mereka yang tidak pernah bekerja dengan teknologi ini, jadi jumlah kod telah dikurangkan sebanyak mungkin. Mari kita mulakan!

Apakah Hibernate?

Ini adalah salah satu pelaksanaan model ORM yang paling popular. Model hubungan objek menerangkan hubungan antara objek perisian dan rekod dalam pangkalan data. Sudah tentu, fungsi Hibernate sangat luas, tetapi kami akan menumpukan pada fungsi yang paling mudah. Matlamat kami: untuk mencipta aplikasi CRUD (Buat, Baca, Kemas Kini, Padam) yang akan dapat:
  1. Cipta pengguna (Pengguna), serta cari mereka dalam pangkalan data dengan ID, kemas kini data mereka dalam pangkalan data, dan juga padamkannya daripada pangkalan data.
  2. Berikan objek kenderaan (Auto) kepada pengguna. Cipta, edit, cari dan padam kereta daripada pangkalan data.
  3. Di samping itu, aplikasi harus mengalih keluar kereta "anak yatim" secara automatik daripada pangkalan data. Itu. Apabila pengguna dipadamkan, semua kereta miliknya juga mesti dipadamkan daripada pangkalan data.
Struktur projek kami adalah seperti berikut: Aplikasi Hibernate pertama anda - 2Seperti yang anda lihat, tiada yang rumit. 6 kelas + 1 fail dengan konfigurasi. Mula-mula, mari buat projek maven baharu dalam Intellij Idea. Fail -> Projek Baharu. Daripada jenis projek yang dicadangkan, pilih Maven dan teruskan. Aplikasi Hibernate pertama anda - 3Apache Maven ialah rangka kerja untuk mengautomasikan pemasangan projek berdasarkan penerangan strukturnya dalam fail dalam bahasa POM. Keseluruhan struktur projek anda akan diterangkan dalam fail pom.xml, yang IDEA sendiri akan cipta dalam akar projek anda. Dalam tetapan projek anda perlu menentukan parameter Maven - groupId dan artifactId. Biasanya dalam projek groupId ialah nama organisasi atau bahagian, dan nama domain organisasi atau tapak projek ditulis di sana. Sebaliknya, artifactId ialah nama projek. Untuk groupdId anda boleh tentukan com.вашНикнейм.javarush, ini tidak akan menjejaskan pengendalian aplikasi dalam apa jua cara. Untuk artifactId, pilih mana-mana nama projek yang anda suka. Anda juga boleh membiarkan Versi tidak berubah. Aplikasi Hibernate pertama anda - 4Pada skrin terakhir, hanya sahkan data yang anda masukkan sebelum ini. Aplikasi Hibernate pertama anda - 5Jadi, kami telah mencipta projek itu, yang tinggal hanyalah menulis kod dan menjadikannya berfungsi :) Pertama sekali, jika kami ingin mencipta aplikasi yang berfungsi dengan pangkalan data, kami pasti tidak boleh melakukannya tanpa pangkalan data! Muat turun PostgreSQL dari sini (saya menggunakan versi 9). PostgreSQL mempunyai 'postgres' pengguna lalai, anda perlu mencipta kata laluan untuknya semasa pemasangan. Jangan lupa kata laluan anda, kami akan memerlukannya kemudian! (Secara amnya, menggunakan pangkalan data lalai dalam aplikasi adalah amalan yang tidak baik, tetapi untuk mengurangkan jumlah buasir, kami akan melakukannya dengan mencipta pangkalan data kami sendiri). Jika anda tidak selesa dengan baris arahan dan pertanyaan SQL, ada berita baik. Intellij IDEA menyediakan antara muka pengguna yang agak sesuai untuk bekerja dengan pangkalan data. Ia kelihatan seperti ini: Aplikasi Hibernate pertama anda - 6(terletak pada bar sisi kanan IDEA, tab Pangkalan Data) Untuk membuat sambungan, klik “+”, pilih pembekal kami (PostgeSQL). Isikan medan dengan pengguna, nama pangkalan data (kedua-duanya adalah postgres) dan masukkan kata laluan yang anda tetapkan semasa memasang PostgreSQL. Jika perlu, muat turun pemacu Postgres, ini boleh dilakukan pada halaman yang sama ini. Klik "Ujian Sambungan" untuk menyemak sama ada sambungan ke pangkalan data telah diwujudkan. Jika anda melihat tulisan "Berjaya", kami teruskan. Sekarang mari kita buat jadual yang kita perlukan. Akan ada dua daripadanya - pengguna dan auto. Parameter untuk jadual pengguna: Permohonan pertama anda pada Hibernate - 7Sila ambil perhatian bahawa id ialah kunci utama. Jika anda tidak tahu apa kunci utama dalam SQL, Google ia, ia penting. Tetapan untuk jadual autos: Permohonan pertama anda pada Hibernate - 8Untuk auto anda perlu mengkonfigurasi Foreign Key - foreign key. Ia akan memautkan jadual kami. Saya menasihati anda untuk membaca lebih lanjut mengenainya; Secara ringkasnya, ia merujuk kepada jadual luaran, dalam kes kami, pengguna. Jika kereta itu milik pengguna dengan id=1, maka dalam medan user_id pada jadual autos ia akan mempunyai 1. Beginilah cara kami menghubungkan pengguna dengan kereta mereka dalam aplikasi kami. Dalam jadual autos kami, medan user_id akan berfungsi sebagai kunci asing. Ia akan merujuk kepada medan id jadual pengguna. Aplikasi Hibernate pertama anda - 9Oleh itu, kami telah mencipta pangkalan data dengan dua jadual. Ia kekal untuk memahami cara mengurusnya daripada kod Java. Kami akan mulakan dengan fail pom.xml, di mana kami perlu memasukkan perpustakaan yang diperlukan (dalam bahasa Maven ia dipanggil dependencies). Semua perpustakaan disimpan dalam repositori pusat Maven. Mereka yang anda tentukan dalam pom.xml, anda boleh gunakan dalam projek itu. Pom.xml anda sepatutnya kelihatan seperti ini: Aplikasi Hibernate pertama anda - 10Tiada apa-apa yang rumit seperti yang anda lihat. Kami menambah hanya 2 kebergantungan - untuk menggunakan PostgreSQL dan Hibernate. Sekarang mari kita beralih kepada kod Java. Buat semua pakej dan kelas yang diperlukan untuk projek itu. Sebagai permulaan, kami memerlukan model data - kelas Userdan 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;
    }
}
Seperti yang anda lihat, kelas dilengkapi dengan sekumpulan anotasi yang masih tidak jelas. Mari kita mula berurusan dengan mereka. Anotasi utama untuk kami ialah @Entity. Baca mengenainya di Wikipedia dan ingat segala-galanya, ini adalah asas asas. Anotasi ini membolehkan objek Java kelas anda dikaitkan dengan pangkalan data. Untuk kelas menjadi entiti, ia mesti memenuhi keperluan berikut:
  • Mesti mempunyai pembina kosong ( publicatau protected);
  • Tidak boleh bersarang, antara muka atau enum;
  • Tidak boleh finaldan tidak boleh mengandungi final-fields/properties;
  • Mesti mengandungi sekurang-kurangnya satu medan @Id.
Semak kelas entiti anda, ini adalah tempat yang sangat popular untuk menembak diri sendiri. Sangat mudah untuk melupakan sesuatu. Dalam kes ini, entiti boleh:
  • Mengandungi pembina bukan kosong;
  • Untuk diwarisi dan untuk diwarisi;
  • Mengandungi kaedah lain dan melaksanakan antara muka.
Seperti yang anda lihat, kelas ini Usersangat serupa dengan jadual pengguna. Ada padang id, name, age. Anotasi yang terletak di atasnya tidak memerlukan banyak penjelasan: sudah jelas bahawa @Id ialah petunjuk bahawa medan adalah pengecam objek kelas ini. Anotasi @Table di atas kelas menentukan nama jadual tempat objek ditulis. Beri perhatian pada ulasan di atas medan umur: jika nama medan dalam kelas dan jadual adalah sama, anda tidak perlu menambah anotasi @Column, ia akan berfungsi seperti itu. Mengenai "strategi = GenerationType.IDENTITY" yang ditunjukkan dalam kurungan: terdapat beberapa strategi penjanaan ID. Anda boleh google, tetapi dalam rangka aplikasi kami, anda tidak perlu bersusah payah. Perkara utama ialah id untuk objek kami akan dijana secara automatik, jadi tiada penetap untuk id, dan kami juga tidak menyatakannya dalam pembina. UserWalau bagaimanapun, kelas itu masih menonjol dalam beberapa perkara . Dia ada senarai kereta! Anotasi @OneToMany muncul di atas senarai. Ini bermakna bahawa satu objek kelas pengguna boleh sepadan dengan beberapa mesin. Tetapan "mappedBY" menghala ke medan pengguna kelas Auto. Dengan cara ini, mesin dan pengguna disambungkan antara satu sama lain. Tetapan orphanRemoval diterjemahkan dengan baik daripada bahasa Inggeris - “remove orphans”. Jika kami memadamkan pengguna daripada pangkalan data, semua kereta yang dikaitkan dengannya juga akan dipadamkan. Sebaliknya, dalam kelas Autoanda akan melihat medan pengguna dengan anotasi @ManyToOne (banyak Auto boleh sepadan dengan satu Pengguna) dan anotasi @JoinColumn. Ia menunjukkan melalui lajur mana dalam jadual autos sambungan dengan jadual pengguna berlaku (kunci asing yang sama yang kita bincangkan sebelum ini). Selepas mencipta model data, tiba masanya untuk mengajar program kami untuk melaksanakan operasi pada data ini dalam pangkalan data. Mari kita mulakan dengan kelas utiliti HibernateSessionFactoryUtil. Ia hanya mempunyai satu tugas - untuk mencipta kilang sesi untuk aplikasi kami berfungsi dengan pangkalan data (hello, corak "Kilang!"). Dia tidak boleh berbuat apa-apa lagi.
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;
    }
}
Dalam kelas ini, kami mencipta objek konfigurasi baharu, Konfigurasi, dan menyampaikan kepadanya kelas yang sepatutnya dilihat sebagai entiti - Userdan Auto. Beri perhatian kepada kaedah configuration.getProperties(). Apakah sifat-sifat lain? di mana? Sifat ialah parameter untuk cara hibernate berfungsi, dinyatakan dalam fail khas hibernate.cfg.xml. Aplikasi Hibernate pertama anda - 11Hibernate.cfg.xml dibaca di sini: new Configuration().configure(); Seperti yang anda lihat, tiada apa-apa yang istimewa di dalamnya - parameter untuk menyambung ke pangkalan data, dan parameter khas show_sql. Ia diperlukan supaya semua pertanyaan SQL yang hibernate akan dilaksanakan terhadap pangkalan data kami adalah output kepada konsol. Dengan cara ini, anda akan melihat dengan tepat apa yang Hibernate lakukan pada setiap masa dan menyingkirkan kesan "ajaib". Seterusnya kita memerlukan kelas UserDAO. (Dengan cara yang baik, anda perlu memprogramkan melalui antara muka - cipta antara muka UserDAOdan laksanakan secara berasingan UserDAOImpl, tetapi untuk mengurangkan jumlah kod saya akan meninggalkan ini. Jangan lakukan ini dalam projek sebenar!). DAO (objek akses data) ialah salah satu corak reka bentuk yang paling biasa, "Akses Data". Maksudnya mudah - untuk mencipta lapisan dalam aplikasi yang hanya bertanggungjawab untuk mengakses data, dan tidak ada yang lain. Dapatkan data daripada pangkalan data, kemas kini data, padam data - dan itu sahaja. Baca lebih lanjut tentang DAO; anda akan menggunakannya secara berterusan dalam kerja anda. Apa yang kelas kita boleh buat UserDao? Sebenarnya, seperti semua DAO, ia hanya boleh berfungsi dengan data. Cari pengguna mengikut id, kemas kini datanya, padamkannya, tarik keluar senarai semua pengguna daripada pangkalan data atau simpan pengguna baharu dalam pangkalan data - itu sahaja fungsinya.
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;
    }
}
Kaedah UserDaoadalah serupa antara satu sama lain. Dalam kebanyakannya, kami menerima objek Sesi (sesi yang menyambung ke pangkalan data kami) menggunakan Kilang Sesi kami, mencipta satu transaksi dalam sesi ini, melakukan transformasi data yang diperlukan, menyimpan hasil transaksi dalam pangkalan data dan menutup sesi. Kaedah itu sendiri, seperti yang anda lihat, agak mudah. DAO ialah "jantung" permohonan kami. Walau bagaimanapun, kami tidak akan mencipta DAO secara langsung dan memanggil kaedahnya dalam main(). Semua logik akan dipindahkan ke 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);
    }


}
Perkhidmatan ialah lapisan data dalam aplikasi yang bertanggungjawab untuk melaksanakan logik perniagaan. Jika program anda perlu melaksanakan beberapa logik perniagaan, ia melakukannya melalui perkhidmatan. Perkhidmatan ini mengandungi dalam dirinya sendiri UserDaodan memanggil kaedah DAO dalam kaedahnya. Ini mungkin kelihatan seperti pertindihan fungsi kepada anda (mengapa tidak hanya memanggil kaedah dari objek dao), tetapi dengan sejumlah besar objek dan logik yang kompleks, memecahkan aplikasi ke dalam lapisan mempunyai faedah yang besar (ini adalah amalan yang baik, ingat maklumat ini untuk masa hadapan dan baca tentang "lapisan aplikasi" "). Dalam perkhidmatan kami, logiknya mudah, tetapi dalam projek sebenar, kaedah perkhidmatan akan mengandungi lebih daripada satu baris kod :) Kini kami mempunyai semua yang kami perlukan untuk aplikasi berfungsi! Mari kita cipta main()pengguna dan mesin untuknya dalam kaedah, sambungkan antara satu sama lain dan simpannya dalam pangkalan data.
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);
    }
}
Seperti yang anda lihat, jadual pengguna mempunyai entri sendiri, dan jadual autos mempunyai entrinya sendiri. Aplikasi Hibernate pertama anda - 13Aplikasi Hibernate pertama anda - 14Mari cuba namakan semula pengguna kami. Mari kosongkan jadual pengguna dan jalankan kod
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);
    }
}
Berfungsi! Aplikasi Hibernate pertama anda - 15Bagaimana jika anda memadamkan pengguna? Mari kosongkan jadual pengguna (autos akan mengosongkan dirinya sendiri) dan laksanakan kod tersebut
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);
    }
}
Dan jadual kami benar-benar kosong (perhatikan konsol, semua pertanyaan yang Hibernate telah dilaksanakan akan dipaparkan di sana). Anda boleh bermain-main dengan aplikasi dan mencuba semua cirinya. Contohnya, cipta pengguna dengan mesin, simpannya dalam pangkalan data, lihat ID yang diberikan kepadanya dan cuba gunakan kaedah main()untuk "menarik" pengguna daripada pangkalan data dengan id ini dan memaparkan senarai mesinnya dalam konsol . Sudah tentu, kami hanya melihat sebahagian kecil daripada fungsi Hibernate. Keupayaannya sangat luas, dan ia telah lama menjadi salah satu piawaian industri untuk pembangunan Java. Jika anda ingin mengkajinya secara terperinci, saya boleh mengesyorkan buku "Java Persistence API and Hibernate", yang saya semak dalam salah satu artikel saya sebelum ini. Saya harap artikel ini berguna kepada pembaca. Jika anda mempunyai sebarang soalan, tanya mereka dalam komen, saya akan dengan senang hati menjawab :) Juga, jangan lupa untuk menyokong pengarang dalam pertandingan dengan "Suka" dia. Atau lebih baik lagi - "Saya sangat menyukainya" :) Semoga berjaya dalam pelajaran anda!
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION