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 :) Hello 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:
Sekarang mari kita beralih kepada kod Java. Buat semua pakej dan kelas yang diperlukan untuk projek itu. Sebagai permulaan, kami memerlukan model data - kelas
- Intellij Idea Ultimate Edition;
Muat turun dari tapak web rasmi dan aktifkan versi percubaan 30 hari. - PostgeSQL ialah salah satu sistem pengurusan pangkalan data moden (DBMS);
- Maven (sudah terbina dalam IDEA);
- Sabar sikit.
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:- Cipta pengguna (Pengguna), serta cari mereka dalam pangkalan data dengan ID, kemas kini data mereka dalam pangkalan data, dan juga padamkannya daripada pangkalan data.
- Berikan objek kenderaan (Auto) kepada pengguna. Cipta, edit, cari dan padam kereta daripada pangkalan data.
- 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.
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. Pada skrin terakhir, hanya sahkan data yang anda masukkan sebelum ini. Jadi, 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: (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: Sila ambil perhatian bahawa id ialah kunci utama. Jika anda tidak tahu apa kunci utama dalam SQL, Google ia, ia penting. Tetapan untuk jadual autos: Untuk 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. Oleh 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: Tiada apa-apa yang rumit seperti yang anda lihat. Kami menambah hanya 2 kebergantungan - untuk menggunakan PostgreSQL dan Hibernate.
User
dan 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 (
public
atauprotected
); - Tidak boleh bersarang, antara muka atau
enum
; - Tidak boleh
final
dan tidak boleh mengandungifinal
-fields/properties; - Mesti mengandungi sekurang-kurangnya satu medan @Id.
- Mengandungi pembina bukan kosong;
- Untuk diwarisi dan untuk diwarisi;
- Mengandungi kaedah lain dan melaksanakan antara muka.
User
sangat 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. User
Walau 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 Auto
anda 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 - User
dan 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. Hibernate.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 UserDAO
dan 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 UserDao
adalah 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 UserDao
dan 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. Mari 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! Bagaimana 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!
GO TO FULL VERSION