CodeGym /Java Blog /Acak /Aplikasi Hibernasi pertama Anda
John Squirrels
Level 41
San Francisco

Aplikasi Hibernasi pertama Anda

Dipublikasikan di grup Acak
Pada artikel ini, Anda akan mengenal salah satu kerangka kerja perusahaan paling populer untuk Java dan membuat aplikasi Hibernasi pertama Anda. Pernah mendengar tentang Hibernasi? Atau mungkin Anda pernah mendengarnya, tetapi belum pernah menggunakannya? Atau mungkin Anda mencoba menggunakannya, tetapi gagal? Dalam ketiga kasus - selamat datang di bawah potongan :) Aplikasi Hibernasi pertama Anda - 1 Halo, semuanya! Pada artikel ini, saya akan berbicara tentang fitur utama framework Hibernate dan membantu Anda menulis aplikasi mini pertama Anda. Untuk ini, kita membutuhkan:
  1. IntelliJ IDEA Ultimate Edition
    Unduh dari situs web resmi dan aktifkan versi uji coba 30 hari.
  2. PostgreSQL - salah satu sistem manajemen basis data modern (DBMS) paling populer
  3. Maven (sudah terhubung ke IDEA)
  4. Sedikit kesabaran.
Untuk berjaga-jaga, saya memposting kode aplikasi di GitHub (cabang codegym). Artikel ini terutama ditujukan bagi mereka yang belum pernah bekerja dengan teknologi ini sebelumnya, jadi saya telah meminimalkan jumlah kodenya. Mari kita mulai!

Apa itu Hibernasi?

Ini adalah salah satu implementasi object-relational mapping (ORM) yang paling populer. Pemetaan objek-relasional mendefinisikan hubungan antara objek perangkat lunak dan catatan basis data. Tentu saja, Hibernasi memiliki fungsi yang sangat luas, tetapi kami akan fokus pada fungsi yang paling sederhana. Tujuan kami adalah membuat aplikasi CRUD (Buat, Baca, Perbarui, Hapus) yang dapat:
  1. Buat pengguna (User), cari mereka di database berdasarkan ID, perbarui data mereka di database, dan hapus dari database.
  2. Tetapkan objek mobil (Otomatis) kepada pengguna. Buat, perbarui, temukan, dan hapus mobil dari database.
  3. Selain itu, aplikasi harus secara otomatis menghapus mobil "tanpa pemilik" dari database. Dengan kata lain, saat pengguna dihapus, semua mobil milik pengguna tersebut juga harus dihapus dari database.
Proyek kami akan disusun seperti ini: Aplikasi Hibernasi pertama Anda - 2Seperti yang Anda lihat, tidak ada yang rumit. 6 kelas + 1 file dengan konfigurasi. Pertama, buat proyek Maven baru di IntelliJ IDEA. File -> Proyek Baru. Pilih Maven dari antara jenis proyek yang diusulkan dan lanjutkan ke langkah berikutnya. Aplikasi Hibernasi pertama Anda - 3Apache Maven adalah kerangka kerja untuk membangun proyek secara otomatis berdasarkan deskripsi strukturnya dalam file POM. Seluruh struktur proyek Anda akan dijelaskan dalam pom.xml, sebuah file yang akan dibuat oleh IDEA sendiri di root proyek Anda. Di pengaturan proyek, Anda perlu menentukan pengaturan Maven berikut: groupId dan artifactId. Dalam proyek, groupId biasanya merupakan deskripsi perusahaan atau unit bisnis. Nama domain perusahaan atau situs web bisa masuk ke sini. Pada gilirannya, artifactId adalah nama proyek. Untuk groupdId, Anda dapat memasukkan com.yourNickname.codegym. Ini tidak akan berpengaruh pada aplikasi. Untuk artifactId, pilih nama project yang Anda suka. Versi dapat dibiarkan tidak berubah. Aplikasi Hibernasi pertama Anda - 4Di layar terakhir, cukup konfirmasikan data yang dimasukkan sebelumnya.Aplikasi Hibernasi pertama Anda - 5Jadi, kami membuat proyek. Sekarang yang harus dilakukan hanyalah menulis beberapa kode dan membuatnya berfungsi :) Hal pertama yang pertama: jika kita ingin membuat aplikasi yang bekerja dengan database, kita pasti tidak dapat melakukannya tanpa database! Unduh PostgreSQL dari sini (Saya menggunakan versi 9). PostgreSQL memiliki pengguna default 'postgres' — Anda harus memikirkan kata sandinya saat menginstal. Jangan lupa kata sandinya. Kami akan membutuhkannya nanti! (Secara umum, menggunakan database default dalam aplikasi adalah praktik yang buruk, tetapi kami akan melakukannya untuk mengurangi jumlah penyebab bisul dengan membuat database Anda sendiri). Jika Anda tidak terbiasa dengan baris perintah dan kueri SQL, ada kabar baik. IntelliJ IDEA menyediakan antarmuka pengguna yang sepenuhnya cocok untuk bekerja dengan database. Aplikasi Hibernasi pertama Anda - 6(terletak di panel kanan IDEA, tab Database). Untuk membuat koneksi, klik "+" dan pilih sumber data kami (PostgeSQL). Isi kolom untuk pengguna dan basis data ("postgres" untuk keduanya) dan masukkan kata sandi yang ditetapkan selama instalasi PostgreSQL. Jika perlu, unduh driver Postgres. Anda dapat melakukan ini di halaman yang sama. Klik "Uji Koneksi" untuk memverifikasi bahwa koneksi database dibuat. Jika Anda melihat "Berhasil", lanjutkan. Sekarang kita akan membuat tabel yang kita butuhkan. Akan ada total dua: pengguna dan mobil. Parameter untuk tabel pengguna: Aplikasi Hibernasi pertama Anda - 7Perhatikan bahwa id adalah kunci utama. Jika Anda tidak tahu apa kunci utama dalam SQL, Google itu. Ini penting. Pengaturan untuk tabel otomatis: Aplikasi Hibernasi pertama Anda - 8Untuk tabel autos, Anda perlu mengonfigurasi kunci asing. Ini akan berfungsi untuk menautkan tabel kami. Saya sarankan Anda membaca lebih lanjut tentang itu. Sederhananya, ini mereferensikan tabel eksternal, dalam kasus kami, pengguna. Jika mobil milik pengguna dengan id = 1, maka kolom user_id dari autos akan sama dengan 1. Beginilah cara kami mengaitkan pengguna dengan mobil mereka di aplikasi kami. Di tabel autos kami, bidang user_id akan bertindak sebagai kunci asing. Ini akan merujuk ke bidang id dari tabel pengguna. Aplikasi Hibernasi pertama Anda - 9Jadi, kami telah membuat database dengan dua tabel. Yang tersisa adalah memahami cara mengelolanya dari kode Java. Kami akan mulai dengan file pom.xml, di mana kami perlu menyertakan pustaka yang diperlukan (di Maven disebut dependensi). Semua perpustakaan disimpan di repositori pusat Maven. Pustaka yang Anda tentukan di pom.xml tersedia untuk Anda gunakan dalam proyek. Pom.xml Anda akan terlihat seperti ini: Aplikasi Hibernasi pertama Anda - 10Tidak ada yang rumit, seperti yang Anda lihat. Kami hanya menambahkan 2 dependensi — untuk menggunakan PostgreSQL dan Hibernate. Sekarang mari beralih ke kode Java. Buat semua paket dan kelas yang diperlukan dalam proyek. Untuk memulai, kita 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 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;
     }
 }
 
 
Seperti yang Anda lihat, kelas memiliki banyak anotasi yang tidak jelas. Mari kita mulai menggalinya. Bagi kami, anotasi utamanya adalah @Entity. Baca tentang itu di Wikipedia dan pelajari semuanya dengan hati. Ini adalah dasar dari yayasan. Anotasi ini memungkinkan objek kelas Java Anda dipetakan ke database. Untuk kelas menjadi entitas, itu harus memenuhi persyaratan berikut:
  • Itu harus memiliki konstruktor kosong ( publicatau protected)
  • Itu tidak dapat disarangkan, antarmuka atauenum
  • Itu tidak bisa finaldan tidak bisa memiliki finalbidang/properti
  • Itu harus memiliki setidaknya satu bidang @Id.
Periksa kelas entitas Anda: mereka adalah tempat yang sangat populer untuk memotret diri sendiri. Sangat mudah untuk melupakan sesuatu. Selain itu, entitas dapat melakukan hal berikut:
  • Itu dapat memiliki konstruktor yang tidak kosong
  • Itu bisa mewarisi dan diwariskan
  • Itu dapat memiliki metode lain dan mengimplementasikan antarmuka.
Seperti yang Anda lihat, kelasnya Usersangat mirip dengan tabel pengguna. Memiliki id, name, danagebidang. Anotasi yang terletak di atasnya tidak memerlukan penjelasan khusus: jelas bahwa @Id menunjukkan bahwa bidang adalah pengidentifikasi objek kelas ini. Anotasi @Table di atas kelas menunjukkan nama tabel tempat objek ditulis. Perhatikan komentar di atas bidang umur: jika nama bidang di kelas sama dengan nama tabel, Anda dapat menghilangkan anotasi @Column dan itu akan berhasil. Adapun bagian yang ditunjukkan dalam tanda kurung ("strategi = GenerationType.IDENTITY"): ada beberapa strategi untuk menghasilkan ID. Anda dapat Google mereka, tetapi untuk aplikasi kami, tidak perlu repot. Hal utama adalah bahwa untuk objek kita nilai id akan dihasilkan secara otomatis. Oleh karena itu, tidak ada penyetel untuk id, dan kami juga tidak menyetelnya di konstruktor. Namun,Userkelas memang menonjol. Ini memiliki daftar mobil! Aplikasi Hibernasi pertama Anda - 11Anotasi @OneToMany tergantung di atas daftar. Ini berarti bahwa beberapa mobil dapat berkorespondensi dengan objek yang sama dari kelas Pengguna. Elemen "mappedBy" mengacu pada bidang pengguna kelas Auto. Dengan demikian, mobil dan pengguna saling terkait. Elemen OrphanRemoval menunjukkan apakah akan menerapkan operasi hapus ke entitas yang tidak lagi memiliki hubungan. Jika kami menghapus pengguna dari database, maka semua mobil yang terkait dengannya juga akan dihapus. Pada gilirannya, diAutokelas, Anda akan melihat bidang pengguna dengan anotasi @ManyToOne (satu Pengguna dapat sesuai dengan banyak Autos) dan anotasi @JoinColumn. Ini menunjukkan kolom mana dalam tabel autos yang digunakan untuk mereferensikan tabel pengguna (yaitu kunci asing yang telah kita bicarakan sebelumnya). Setelah membuat model data, saatnya mengajarkan program kita untuk melakukan operasi dengan data di database. Mari kita mulai dengan kelas utilitas HibernateSessionFactoryUtil. Ini hanya memiliki satu tugas — untuk membuat pabrik sesi agar aplikasi kita bekerja dengan database (sapa pola desain Pabrik!). Ia tidak tahu bagaimana melakukan hal lain.

 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;
     }
 }
 
Di kelas ini, kami membuat objek Konfigurasi baru, dan meneruskannya ke kelas yang harus diperlakukan sebagai entitas: Userdan Auto. Perhatikan metodenya configuration.getProperties(). Properti apa lagi yang ada? Mereka berasal dari mana? Properti adalah pengaturan hibernasi yang ditunjukkan dalam file khusus hibernate.cfg.xml. Aplikasi Hibernasi pertama Anda - 12Hibernate.cfg.xml dibaca di sini: new Configuration().configure(); Seperti yang Anda lihat, tidak ada yang istimewa tentangnya: Hibernate.cfg.xml berisi parameter untuk menghubungkan ke database, serta parameter show_sql. Ini diperlukan agar semua kueri sql yang dijalankan oleh Hibernate ditampilkan di konsol. Dengan cara ini Anda akan melihat dengan tepat apa yang dilakukan Hibernate pada saat tertentu, menghilangkan rasa "sihir". Selanjutnya kita membutuhkanUserDAOkelas. Praktik terbaik adalah memprogram melalui antarmuka — buat UserDAOantarmuka dan UserDAOImplimplementasi terpisah, tetapi saya akan melewatkan ini untuk mengurangi jumlah kode. Jangan lakukan ini dalam proyek nyata! Pola desain DAO (objek akses data) adalah salah satu yang paling umum. Idenya sederhana — buat lapisan aplikasi yang hanya bertanggung jawab untuk mengakses data, tidak lebih. Ambil data dari database, perbarui data, hapus data — itu saja. Pelajari lebih lanjut tentang DAO. Anda akan menggunakan objek akses data terus-menerus dalam pekerjaan Anda. Apa yang bisa dilakukan kelas kita UserDao? Yah, seperti semua DAO, itu hanya bisa bekerja dengan data. Temukan pengguna berdasarkan id, perbarui datanya, hapus, dapatkan daftar semua pengguna dari database, atau simpan pengguna baru di database — itulah keseluruhan 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;
     }
 }
 
UserDaoMetodenya mirip satu sama lain. Di sebagian besar dari mereka, kami mendapatkan objek Sesi (sesi koneksi basis data) menggunakan Pabrik Sesi kami, membuat satu transaksi dalam sesi ini, melakukan manipulasi data yang diperlukan, menyimpan hasil transaksi dalam basis data, dan kemudian menutup sesi. Metodenya sendiri, seperti yang Anda lihat, cukup sederhana. DAO adalah "jantung" dari aplikasi kita. Namun, kami tidak akan membuat DAO secara langsung dan memanggil metodenya dalam main()metode kami. Semua logika akan dipindahkan ke UserServicekelas.

 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);
     }
 
 
 }
 
 
Layanan adalah lapisan data aplikasi yang bertanggung jawab untuk menjalankan logika bisnis. Jika program Anda perlu menjalankan semacam logika bisnis, ia melakukannya melalui layanan. Layanan berisi UserDaodan memanggil metode DAO dalam metodenya. Sepertinya kita menduplikasi fungsi di sini (mengapa tidak memanggil metode dari objek DAO saja?), tetapi dengan banyak objek dan logika kompleks, melapisi aplikasi memberikan keuntungan besar (melakukannya adalah praktik yang baik — ingat ini di masa mendatang dan baca tentang "lapisan aplikasi"). Layanan kami memiliki logika sederhana, tetapi metode layanan dalam proyek dunia nyata mengandung lebih dari satu baris kode :) Sekarang kami memiliki semua yang Anda butuhkan untuk menjalankan aplikasi! Dalam main()metode ini, mari buat pengguna dan mobilnya, kaitkan satu sama lain, dan simpan di 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 ("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);
     }
 }
 
 
Seperti yang Anda lihat, tabel users memiliki catatannya sendiri, dan tabel autos memiliki catatannya sendiri. Aplikasi Hibernasi pertama Anda - 13Aplikasi Hibernasi pertama Anda - 14Mari coba ganti nama pengguna kita. Kosongkan tabel pengguna dan jalankan kode

 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);
     }
 }
 
 
Berhasil! Aplikasi Hibernasi pertama Anda - 15Bagaimana jika Anda menghapus pengguna? Bersihkan tabel pengguna (otomatis akan menghapus sendiri) dan jalankan kodenya

 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);
     }
 }
 
 
Dan tabel kami benar-benar kosong (perhatikan konsol - semua permintaan yang dilakukan oleh Hibernate akan ditampilkan di sana). Anda dapat bermain-main dengan aplikasi dan mencoba semua fungsinya. Misalnya, buat pengguna dengan mobil, simpan di database, lihat id yang diberikan kepada pengguna, dan coba gunakan id ini dimain()metode untuk mengambil pengguna dari database dan menampilkan daftar mobilnya di konsol. Tentu saja, kami hanya melihat sebagian kecil dari fungsi Hibernate. Kemampuannya sangat luas, dan telah lama menjadi alat industri standar untuk pengembangan Java. Jika Anda ingin mempelajarinya secara detail, saya dapat merekomendasikan buku "Java Persistence API and Hibernate". Saya ulas di artikel sebelumnya. Semoga artikel ini bermanfaat bagi para pembaca. Jika Anda memiliki pertanyaan, tanyakan di komentar. Saya akan dengan senang hati menjawab :) Juga, jangan lupa untuk mendukung penulis dalam kontes dengan memposting "Suka". Atau lebih baik lagi — "Suka" :) Semoga berhasil dalam studi Anda!
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION