Dalam artikel ini, anda akan menjadi biasa dengan salah satu rangka kerja perusahaan yang paling popular untuk Java dan mencipta aplikasi Hibernate pertama anda. Tidak pernah mendengar tentang Hibernate? Atau mungkin anda pernah mendengarnya, tetapi tidak menggunakannya? Atau mungkin anda cuba menggunakannya, tetapi gagal? Dalam ketiga-tiga kes - selamat datang ke bahagian bawah :) Hello, semua! Dalam artikel ini, saya akan bercakap tentang ciri utama rangka kerja Hibernate dan membantu anda menulis aplikasi mini pertama anda. Untuk ini, kami memerlukan:
- IntelliJ IDEA Ultimate Edition
Muat turun dari tapak web rasmi dan aktifkan versi percubaan 30 hari. - PostgreSQL - salah satu sistem pengurusan pangkalan data moden (DBMS) yang paling popular
- Maven (sudah disambungkan ke IDEA)
- Sabar sikit.
Apakah Hibernate?
Ia merupakan salah satu pelaksanaan pemetaan hubungan objek (ORM) yang paling popular. Pemetaan hubungan objek mentakrifkan hubungan antara objek perisian dan rekod pangkalan data. Sudah tentu, Hibernate mempunyai fungsi yang sangat luas, tetapi kami akan memberi tumpuan kepada fungsi yang paling mudah. Matlamat kami adalah untuk mencipta aplikasi CRUD (Buat, Baca, Kemas Kini, Padam) yang akan dapat:- Cipta pengguna (Pengguna), cari mereka dalam pangkalan data mengikut ID, kemas kini data mereka dalam pangkalan data, dan padamkannya daripada pangkalan data.
- Berikan objek kereta (Auto) kepada pengguna. Cipta, kemas kini, cari dan padam kereta daripada pangkalan data.
- Selain itu, aplikasi itu harus mengalih keluar kereta "tanpa pemilik" secara automatik daripada pangkalan data. Dalam erti kata lain, apabila pengguna dipadamkan, semua kereta milik pengguna itu juga mesti dipadamkan daripada pangkalan data.
com.yourNickname.codegym
. Ini tidak akan mempunyai apa-apa kesan pada aplikasi. Untuk artifactId, pilih mana-mana nama projek yang anda suka. Versi boleh dibiarkan tidak berubah. Pada skrin terakhir, hanya sahkan data yang dimasukkan sebelum ini.Jadi, kami mencipta projek itu. Sekarang semua yang perlu dilakukan ialah menulis beberapa kod dan menjadikannya berfungsi :) Perkara pertama dahulu: jika kita ingin mencipta aplikasi yang berfungsi dengan pangkalan data, kita pasti tidak boleh melakukannya tanpa pangkalan data! Muat turun PostgreSQL dari sini (saya menggunakan versi 9). PostgreSQL mempunyai 'postgres' pengguna lalai — anda perlu memikirkan kata laluan untuknya apabila anda memasang. Jangan lupa kata laluan. Kami akan memerlukannya nanti! (Secara umum, menggunakan pangkalan data lalai dalam aplikasi adalah amalan buruk, tetapi kami akan melakukannya untuk mengurangkan bilangan punca ulser dengan mencipta pangkalan data anda sendiri). Jika anda tidak berkawan dengan baris arahan dan pertanyaan SQL, ada berita baik. IntelliJ IDEA menyediakan antara muka pengguna yang sesuai sepenuhnya untuk bekerja dengan pangkalan data. (terletak pada anak tetingkap kanan IDEA, tab Pangkalan Data). Untuk membuat sambungan, klik "+" dan pilih sumber data kami (PostgeSQL). Isikan medan untuk pengguna dan pangkalan data ("postgres" untuk kedua-duanya) dan masukkan kata laluan yang telah ditetapkan semasa pemasangan PostgreSQL. Jika perlu, muat turun pemacu Postgres. Anda boleh melakukan ini pada halaman yang sama. Klik "Ujian Sambungan" untuk mengesahkan bahawa sambungan pangkalan data diwujudkan. Jika anda melihat "Berjaya", kemudian teruskan. Sekarang kita akan mencipta jadual yang kita perlukan. Terdapat dua jumlah: pengguna dan auto. Parameter untuk jadual pengguna: Ambil perhatian bahawa id ialah kunci utama. Jika anda tidak tahu apa kunci utama dalam SQL, Google ia. Ini sangat penting. Tetapan untuk jadual autos: Untuk jadual autos, anda perlu mengkonfigurasi kunci asing. Ia akan berfungsi untuk memautkan jadual kami. Saya mengesyorkan anda membaca lebih lanjut mengenainya. Ringkasnya, ia merujuk kepada jadual luaran, dalam kes kami, pengguna. Jika kereta milik pengguna dengan id = 1, maka medan user_id autos akan sama dengan 1. Beginilah cara kami mengaitkan pengguna dengan kereta mereka dalam aplikasi kami. Dalam jadual autos kami, medan user_id akan bertindak sebagai kunci asing. Ia akan merujuk kepada medan id jadual pengguna. Jadi, kami telah mencipta pangkalan data dengan dua jadual. Apa yang tinggal ialah memahami cara mengurusnya daripada kod Java. Kami akan bermula dengan fail pom.xml, di mana kami perlu memasukkan perpustakaan yang diperlukan (dalam Maven ia dipanggil dependencies). Semua perpustakaan disimpan dalam repositori pusat Maven. Perpustakaan yang anda tentukan dalam pom.xml tersedia untuk anda gunakan dalam projek. Pom.xml anda sepatutnya kelihatan seperti ini: Tiada 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 dalam projek. Untuk memulakan, kita memerlukan model data: the User
and Auto
classes.
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 mempunyai banyak anotasi yang tidak jelas. Mari kita mula menggali mereka. Bagi kami, anotasi utama ialah @Entity. Baca tentangnya di Wikipedia dan pelajari semuanya dengan hati. Ini adalah asas asas. Anotasi ini membolehkan objek kelas Java anda dipetakan ke pangkalan data. Untuk kelas menjadi entiti, ia mesti memenuhi keperluan berikut:
- Ia mesti mempunyai pembina kosong (
public
atauprotected
) - Ia tidak boleh bersarang, antara muka atau an
enum
- Ia tidak boleh
final
dan tidak boleh mempunyaifinal
medan/sifat - Ia mesti mempunyai sekurang-kurangnya satu medan @Id.
- Ia boleh mempunyai pembina bukan kosong
- Ia boleh diwarisi dan diwarisi
- Ia boleh mempunyai kaedah lain dan melaksanakan antara muka.
User
kelas ini sangat serupa dengan jadual pengguna. Ia mempunyai id
, name
, danage
padang. Anotasi yang terletak di atasnya tidak memerlukan penjelasan tertentu: jelas bahawa @Id menunjukkan bahawa medan ialah pengecam objek kelas ini. Anotasi @Table di atas kelas menunjukkan nama jadual tempat objek ditulis. Perhatikan ulasan di atas medan umur: jika nama medan dalam kelas adalah sama dengan nama jadual, anda boleh meninggalkan anotasi @Column dan ia akan berfungsi. Bagi bahagian yang ditunjukkan dalam pendakap ("strategi = GenerationType.IDENTITY"): terdapat beberapa strategi untuk menjana ID. Anda boleh Google mereka, tetapi untuk aplikasi kami, tidak perlu bersusah payah. Perkara utama ialah untuk objek kami nilai id akan dijana secara automatik. Sehubungan itu, tiada setter untuk id, dan kami juga tidak menetapkannya dalam pembina. Walau bagaimanapun,User
kelas memang menyerlah. Ia mempunyai senarai kereta! Anotasi @OneToMany tergantung di atas senarai. Ini bermakna bahawa beberapa kereta boleh sepadan dengan objek yang sama dalam kelas Pengguna. Elemen "mappedBy" merujuk kepada medan pengguna kelas Auto
. Oleh itu, kereta dan pengguna adalah berkaitan. Elemen orphanRemoval menunjukkan sama ada hendak menggunakan operasi alih keluar kepada entiti yang tidak lagi mempunyai perhubungan. Jika kami memadamkan pengguna daripada pangkalan data, maka semua kereta yang dikaitkan dengannya juga akan dipadamkan. Sebaliknya, dalamAuto
kelas, anda akan melihat medan pengguna dengan anotasi @ManyToOne (satu Pengguna boleh sepadan dengan banyak Auto) dan anotasi @JoinColumn. Ia menunjukkan lajur dalam jadual autos yang digunakan untuk merujuk jadual pengguna (iaitu kunci asing yang kita bincangkan sebelum ini). Selepas mencipta model data, tiba masanya untuk mengajar program kami untuk melaksanakan operasi dengan data 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 (ucapkan hello kepada corak reka bentuk Kilang!). Ia tidak tahu bagaimana untuk melakukan 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("Исключение!" + e);
}
}
return sessionFactory;
}
}
Dalam kelas ini, kami mencipta objek Konfigurasi baharu, dan memberikannya kepada kelas-kelas yang sepatutnya dianggap sebagai entiti: User
dan Auto
. Beri perhatian kepada configuration.getProperties()
kaedah. Apakah hartanah lain yang ada? Mereka datang dari mana? Sifat ialah tetapan hibernate yang ditunjukkan dalam fail hibernate.cfg.xml khas. Hibernate.cfg.xml dibaca di sini: new Configuration().configure();
Seperti yang anda lihat, tiada apa-apa yang istimewa mengenainya: ia mengandungi parameter untuk menyambung ke pangkalan data, serta parameter show_sql. Ini diperlukan supaya semua pertanyaan sql yang dilaksanakan oleh Hibernate dipaparkan pada konsol. Dengan cara ini anda akan melihat dengan tepat apa yang Hibernate lakukan pada bila-bila masa tertentu, menghapuskan sebarang rasa "sihir". Seterusnya kita memerlukanUserDAO
kelas. Amalan terbaik ialah memprogramkan melalui antara muka — cipta UserDAO
antara muka dan UserDAOImpl
pelaksanaan yang berasingan, tetapi saya akan melangkau ini untuk mengurangkan jumlah kod. Jangan lakukan ini dalam projek sebenar! Corak reka bentuk DAO (objek akses data) adalah salah satu yang paling biasa. Ideanya mudah — buat lapisan aplikasi yang bertanggungjawab hanya untuk mengakses data, tidak lebih. Ambil data daripada pangkalan data, kemas kini data, padam data — itu sahaja. Belajar lebih lanjut tentang DAO. Anda akan menggunakan objek akses data secara berterusan dalam kerja anda. Apa yang kelas kita boleh UserDao
buat? Nah, seperti semua DAO, ia hanya boleh berfungsi dengan data. Cari pengguna mengikut id, kemas kini datanya, padamkannya, dapatkan senarai semua pengguna daripada pangkalan data atau simpan pengguna baharu dalam pangkalan data — 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;
}
}
UserDao
Kaedah adalah serupa antara satu sama lain. Dalam kebanyakannya, kami mendapat objek Sesi (sesi sambungan pangkalan data) menggunakan Kilang Sesi kami, buat satu transaksi dalam sesi ini, lakukan manipulasi data yang diperlukan, simpan hasil transaksi dalam pangkalan data, dan kemudian tutup sesi. Kaedah itu sendiri, seperti yang anda lihat, agak mudah. DAO adalah "jantung" permohonan kami. Walau bagaimanapun, kami tidak akan mencipta DAO secara langsung dan memanggil kaedahnya dalam main()
kaedah kami. Semua logik akan dipindahkan ke UserService
kelas.
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 aplikasi yang bertanggungjawab untuk melaksanakan logik perniagaan. Jika program anda perlu melaksanakan beberapa jenis logik perniagaan, ia melakukannya melalui perkhidmatan. Perkhidmatan mengandungi UserDao
dan memanggil kaedah DAO dalam kaedahnya. Nampaknya kita sedang menduplikasi fungsi di sini (mengapa tidak hanya memanggil kaedah dari objek DAO?), tetapi dengan banyak objek dan logik yang kompleks, lapisan aplikasi memberikan kelebihan yang besar (melakukannya adalah amalan yang baik - ingat ini pada masa hadapan dan baca tentang "lapisan aplikasi"). Perkhidmatan kami mempunyai logik yang mudah, tetapi kaedah perkhidmatan dalam projek dunia sebenar mengandungi lebih daripada satu baris kod :) Kini kami mempunyai semua yang anda perlukan untuk menjalankan aplikasi! Dalam main()
kaedah ini, mari kita cipta pengguna dan keretanya, kaitkan satu dengan yang lain, dan simpan mereka 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 ("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, jadual pengguna mempunyai rekodnya sendiri, dan jadual autos mempunyai rekodnya sendiri. Mari cuba namakan semula pengguna kami. Kosongkan jadual pengguna dan laksanakan 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 ("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);
}
}
Ianya berfungsi! Bagaimana jika anda memadam pengguna? 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 ("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 jadual kami benar-benar kosong (perhatikan konsol — semua permintaan yang dilakukan oleh Hibernate akan dipaparkan di sana). Anda boleh bermain-main dengan aplikasi dan mencuba semua fungsinya. Contohnya, cipta pengguna dengan kereta, simpan dalam pangkalan data, lihat id yang diberikan kepada pengguna dan cuba gunakan id ini dalammain()
kaedah untuk mengambil pengguna daripada pangkalan data dan memaparkan senarai keretanya pada konsol. Sudah tentu, kami hanya melihat sebahagian kecil fungsi Hibernate. Keupayaannya sangat luas, dan ia telah lama menjadi alat industri standard untuk pembangunan Java. Jika anda ingin mengkajinya secara terperinci, saya boleh mengesyorkan buku "Java Persistence API and Hibernate". Saya semak dalam artikel sebelum ini. Saya harap artikel ini dapat membantu pembaca. Jika anda mempunyai soalan, tanya mereka dalam komen. Saya akan dengan senang hati menjawab :) Juga, jangan lupa untuk menyokong penulis dalam peraduan dengan menyiarkan "Like". Atau lebih baik lagi — "Suka hati" :) Semoga berjaya dalam pelajaran anda!
GO TO FULL VERSION