Ushbu maqolada siz Java uchun eng mashhur korporativ ramkalardan biri bilan tanishasiz va Hibernate yordamida birinchi dasturingizni yaratasiz. Hibernate haqida hech qachon eshitmaganmisiz? Balki siz bu haqda eshitgandirsiz, lekin foydalanmagandirsiz? Yoki boshlashga harakat qildingiz, lekin muvaffaqiyatga erishmadingizmi? Har uch holatda ham, kesishga xush kelibsiz :) Hammaga salom! Ushbu maqolada men Hibernate ramkasining asosiy xususiyatlari haqida gapiraman va sizga birinchi mini-ilovangizni yozishda yordam beraman. Buning uchun bizga kerak:
Endi Java kodiga o'tamiz. Loyiha uchun barcha kerakli paketlar va sinflarni yarating. Boshlash uchun bizga ma'lumotlar modellari kerak bo'ladi - sinflar
- Intellij Idea Ultimate Edition; Rasmiy veb-saytdan
yuklab oling va 30 kunlik sinov versiyasini faollashtiring. - PostgeSQL - eng mashhur zamonaviy ma'lumotlar bazasini boshqarish tizimlaridan biri (DBMS);
- Maven (IDEA-ga allaqachon o'rnatilgan);
- Bir oz sabr.
Hibernate nima?
Bu ORM modelining eng mashhur ilovalaridan biridir. Ob'ektga aloqador model dasturiy ta'minot ob'ektlari va ma'lumotlar bazasidagi yozuvlar o'rtasidagi munosabatlarni tavsiflaydi. Albatta, Hibernate funksiyasi juda keng, lekin biz eng oddiy funksiyalarga e'tibor qaratamiz. Bizning maqsadimiz: CRUD ilovasini yaratish (Yaratish, O'qish, Yangilash, O'chirish) u:- Foydalanuvchilarni (Foydalanuvchi) yarating, shuningdek ularni ID bo'yicha ma'lumotlar bazasida qidiring, ma'lumotlar bazasidagi ma'lumotlarini yangilang, shuningdek ularni ma'lumotlar bazasidan o'chiring.
- Foydalanuvchilarga avtomobil obyektlarini (Avtomatik) tayinlash. Ma'lumotlar bazasidan avtomobillarni yaratish, tahrirlash, topish va o'chirish.
- Bundan tashqari, dastur avtomatik ravishda ma'lumotlar bazasidan "etim" avtomobillarni olib tashlashi kerak. Bular. Foydalanuvchi o'chirilganda, unga tegishli bo'lgan barcha avtomobillar ham ma'lumotlar bazasidan o'chirilishi kerak.
com.вашНикнейм.javarush
, bu hech qanday tarzda ilovaning ishlashiga ta'sir qilmaydi. ArtifactId uchun o'zingizga yoqqan har qanday loyiha nomini tanlang. Bundan tashqari, Versiyani o'zgarishsiz qoldirishingiz mumkin. Oxirgi ekranda avval kiritilgan ma'lumotlarni tasdiqlash kifoya. Demak, biz loyihani yaratdik, qolgan narsa kodni yozish va uni ishlashi uchun :) Birinchi navbatda, agar biz ma'lumotlar bazasi bilan ishlaydigan dastur yaratmoqchi bo'lsak, biz albatta ma'lumotlar bazasisiz ishlay olmaymiz! PostgreSQL-ni shu yerdan yuklab oling (men 9-versiyadan foydalanaman). PostgreSQL standart foydalanuvchi "postgres" ga ega, o'rnatish vaqtida unga parol yaratishingiz kerak bo'ladi. Parolni unutmang, keyinroq kerak bo'ladi! (Umuman olganda, ilovalarda standart ma'lumotlar bazasidan foydalanish yomon amaliyotdir, ammo gemorroy miqdorini kamaytirish uchun biz o'z ma'lumotlar bazasini yaratish bilan shug'ullanamiz). Agar siz buyruq qatori va SQL so'rovlari bilan qulay bo'lmasangiz, yaxshi yangilik bor. Intellij IDEA ma'lumotlar bazasi bilan ishlash uchun juda mos foydalanuvchi interfeysini taqdim etadi. Bu shunday ko'rinadi: (IDEA-ning o'ng tomonida, Ma'lumotlar bazasi yorlig'ida joylashgan) Ulanishni yaratish uchun "+" tugmasini bosing, provayderimizni tanlang (PostgeSQL). Maydonlarni foydalanuvchi, ma'lumotlar bazasi nomi (ikkalasi ham postgres) bilan to'ldiring va PostgreSQL-ni o'rnatishda o'rnatgan parolni kiriting. Agar kerak bo'lsa, Postgres drayverini yuklab oling, bu xuddi shu sahifada amalga oshirilishi mumkin. Ma'lumotlar bazasiga ulanish o'rnatilganligini tekshirish uchun "Ulanishni sinab ko'rish" tugmasini bosing. Agar siz "Muvaffaqiyatli" yozuvini ko'rsangiz, biz davom etamiz. Endi o'zimizga kerakli jadvallarni yaratamiz. Ulardan ikkitasi bo'ladi - foydalanuvchilar va avtolar. Foydalanuvchilar jadvali parametrlari: Iltimos, id asosiy kalit ekanligini unutmang. Agar siz SQL-da asosiy kalit nima ekanligini bilmasangiz, uni Google-da toping, bu muhim. Avtomatik jadval uchun sozlash: Avtomashinalar uchun siz tashqi kalitni sozlashingiz kerak - tashqi kalit. U bizning jadvallarimizni bog'laydi. Men sizga u haqida ko'proq o'qishni maslahat beraman; Oddiy qilib aytganda, bu tashqi jadvalga, bizning holatlarimizda foydalanuvchilarga tegishli. Agar mashina id=1 bo'lgan foydalanuvchiga tegishli bo'lsa, u holda autos jadvalining user_id maydonida 1 bo'ladi. Biz ilovamizda foydalanuvchilarni avtomobillari bilan shu tarzda bog'laymiz. Bizning autos jadvalimizda user_id maydoni xorijiy kalit sifatida xizmat qiladi. U foydalanuvchilar jadvalining id maydoniga ishora qiladi. Shunday qilib, biz ikkita jadvaldan iborat ma'lumotlar bazasini yaratdik. Uni Java kodidan qanday boshqarishni tushunish qoladi. Biz pom.xml faylidan boshlaymiz, unda biz kerakli kutubxonalarni kiritishimiz kerak (Maven tilida ular bog'liqliklar deb ataladi). Barcha kutubxonalar markaziy Maven omborida saqlanadi. Ulardan siz pom.xml da ko'rsatganingizdan loyihada foydalanishingiz mumkin. Sizning pom.xmlingiz quyidagicha ko'rinishi kerak: Ko'rib turganingizdek, hech qanday murakkab narsa yo'q. Biz faqat ikkita bog'liqlikni qo'shdik - PostgreSQL va Hibernate-dan foydalanish uchun.
User
va 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;
}
}
Ko'rib turganingizdek, sinflar hali ham tushunarsiz izohlar bilan jihozlangan. Keling, ular bilan ishlashni boshlaylik. Biz uchun asosiy izoh @Entity. Vikipediyada bu haqda o'qing va hamma narsani eslang, bu asoslarning asosidir. Ushbu izoh sinfingizning Java ob'ektlarini ma'lumotlar bazasi bilan bog'lash imkonini beradi. Sinf ob'ekt bo'lishi uchun u quyidagi talablarga javob berishi kerak:
- Konstruktor bo'sh bo'lishi kerak (
public
yokiprotected
); - Ichki, interfeys yoki
enum
; - -maydonlar/xususiyatlar bo'lishi mumkin emas
final
va bo'lishi mumkin emas ;final
- Kamida bitta @Id maydoni boʻlishi kerak.
- Bo'sh bo'lmagan konstruktorlarni o'z ichiga oladi;
- Meros bo'lish va meros bo'lish;
- Boshqa usullarni o'z ichiga oladi va interfeyslarni amalga oshiradi.
User
foydalanuvchilar jadvaliga juda o'xshash. Maydonlar mavjud id
, name
, age
. Ularning tepasida joylashgan izohlar ko'p tushuntirishni talab qilmaydi: @Id maydon ushbu sinf ob'ektlarining identifikatori ekanligini ko'rsatishi allaqachon aniq. Sinf ustidagi @Table izohi ob'ektlar yoziladigan jadval nomini bildiradi. Yosh maydoni ustidagi izohga e'tibor bering: agar sinfdagi maydon nomi va jadval bir xil bo'lsa, @Column izohini qo'shishingiz shart emas, u shunday ishlaydi. Qavslar ichida ko'rsatilgan "strategiya = GenerationType.IDENTITY" bo'yicha: bir nechta ID yaratish strategiyalari mavjud. Siz uni Google orqali qidirishingiz mumkin, ammo bizning ilovamiz doirasida siz bezovta qilishingiz shart emas. Asosiysi, bizning ob'ektlarimiz uchun identifikatorlar avtomatik ravishda yaratiladi, shuning uchun id uchun sozlagich yo'q va biz uni konstruktorda ham ko'rsatmaymiz. Biroq, sinf hali ham ba'zi jihatlari User
bilan ajralib turadi . Uning mashinalar ro'yxati bor! @OneToMany izohi roʻyxat tepasida koʻrinadi. Bu foydalanuvchi sinfining bitta ob'ekti bir nechta mashinalarga mos kelishi mumkinligini anglatadi. "mappedBY" sozlamasi sinfning foydalanuvchi maydoniga ishora qiladi Auto
. Shu tarzda, mashinalar va foydalanuvchilar bir-biriga bog'langan. OrphanRemoval sozlamasi ingliz tilidan juda yaxshi tarjima qilingan - "etimlarni olib tashlash". Agar foydalanuvchini ma'lumotlar bazasidan o'chirib tashlasak, u bilan bog'langan barcha avtomobillar ham o'chiriladi. O'z navbatida, sinfda Auto
foydalanuvchi maydonini @ManyToOne izohi (ko'p Autos bir foydalanuvchiga mos kelishi mumkin) va @JoinColumn izohi bilan ko'rasiz. Bu autos jadvalining qaysi ustuni orqali foydalanuvchilar jadvali bilan bog'lanish sodir bo'lishini ko'rsatadi (biz avvalroq gaplashgan bir xil tashqi kalit). Ma'lumotlar modelini yaratgandan so'ng, dasturimizga ma'lumotlar bazasida ushbu ma'lumotlar bilan operatsiyalarni bajarishni o'rgatish vaqti keldi. Keling, HibernateSessionFactoryUtil yordamchi dastur sinfidan boshlaylik. Uning faqat bitta vazifasi bor - bizning ilovamiz uchun ma'lumotlar bazasi bilan ishlash uchun sessiya zavodini yaratish (salom, "Zavod!" naqsh). U boshqa hech narsa qila olmaydi.
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;
}
}
Ushbu sinfda biz yangi konfiguratsiya ob'ektini - Konfiguratsiyani yaratamiz va unga ob'ektlar sifatida qabul qilinishi kerak bo'lgan sinflarni o'tkazamiz - User
va Auto
. Usulga e'tibor bering configuration.getProperties()
. Yana qanday xususiyatlar? Qayerda? Xususiyatlar hibernate.cfg.xml maxsus faylida ko'rsatilgan kutish rejimi qanday ishlashiga oid parametrlardir. Hibernate.cfg.xml bu yerda o'qiladi: new Configuration().configure();
Ko'rib turganingizdek, unda hech qanday maxsus narsa yo'q - ma'lumotlar bazasiga ulanish parametrlari va show_sql maxsus parametri. Bu bizning ma'lumotlar bazasiga qarshi kutish rejimida bo'lgan barcha SQL so'rovlari konsolga chiqishi uchun kerak. Shunday qilib, siz har lahzada Hibernate nima qilayotganini aniq ko'rasiz va "sehrli" effektdan xalos bo'lasiz. Keyin bizga sinf kerak UserDAO
. (Yaxshi ma'noda, siz interfeyslar orqali dasturlashingiz kerak - interfeys yarating UserDAO
va uni alohida amalga oshiring UserDAOImpl
, lekin kod miqdorini kamaytirish uchun men buni o'tkazib yuboraman. Haqiqiy loyihalarda buni qilmang!). DAO (ma'lumotlarga kirish ob'ekti) eng keng tarqalgan dizayn naqshlaridan biri, "Ma'lumotlarga kirish". Uning ma'nosi oddiy - ilovada faqat ma'lumotlarga kirish uchun javobgar bo'lgan qatlam yaratish va boshqa hech narsa emas. Ma'lumotlar bazasidan ma'lumotlarni oling, ma'lumotlarni yangilang, ma'lumotlarni o'chiring - va hammasi. DAOlar haqida ko'proq o'qing; siz ulardan doimiy ravishda ishingizda foydalanasiz. Bizning sinfimiz nima qila oladi UserDao
? Aslida, barcha DAOlar singari, u faqat ma'lumotlar bilan ishlashi mumkin. Foydalanuvchini id bo'yicha toping, uning ma'lumotlarini yangilang, uni o'chiring, ma'lumotlar bazasidan barcha foydalanuvchilar ro'yxatini chiqarib oling yoki ma'lumotlar bazasida yangi foydalanuvchini saqlang - bu uning barcha funktsiyalari.
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;
}
}
Usullar UserDao
bir-biriga o'xshash. Ularning ko'pchiligida biz Session Factory-dan foydalangan holda Sessiya ob'ektini (ma'lumotlar bazasiga ulanadigan seans) olamiz, ushbu sessiya doirasida bitta tranzaksiya yaratamiz, kerakli ma'lumotlarni o'zgartirishni amalga oshiramiz, tranzaksiya natijasini ma'lumotlar bazasida saqlaymiz va sessiyani yopamiz. Ko'rib turganingizdek, usullarning o'zi juda oddiy. DAO bizning dasturimizning "yuragi" dir. Biroq, biz DAO ni to'g'ridan-to'g'ri yaratmaymiz va uning usullarini bizning main()
. Barcha mantiq ga ko'chiriladi 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);
}
}
Xizmat - bu biznes mantig'ini bajarish uchun mas'ul bo'lgan ilovadagi ma'lumotlar qatlami. Agar dasturingiz biznes mantiqini bajarishi kerak bo'lsa, u buni xizmatlar orqali amalga oshiradi. Xizmat o'z ichiga oladi UserDao
va o'z usullarida DAO usullarini chaqiradi. Bu sizga funktsiyalarning takrorlanishi kabi ko'rinishi mumkin (nega faqat dao ob'ektidan usullarni chaqirish emas), lekin ko'p sonli ob'ektlar va murakkab mantiq bilan dasturni qatlamlarga bo'lish juda katta foyda keltiradi (bu yaxshi amaliyot, bu ma'lumotni eslab qoling. kelajak va "ilova qatlamlari" haqida o'qing "). Bizning xizmatimizda mantiq oddiy, ammo haqiqiy loyihalarda xizmat ko'rsatish usullari bir nechta kod qatorini o'z ichiga oladi :) Endi bizda dastur ishlashi uchun kerak bo'lgan hamma narsa mavjud! main()
Usulda unga foydalanuvchi va mashinalarni yaratamiz , ularni bir-biriga bog'laymiz va ma'lumotlar bazasida saqlaymiz.
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);
}
}
Ko'rib turganingizdek, foydalanuvchilar jadvali o'z yozuviga ega va autos jadvalining o'ziga xos yozuvi mavjud. Keling, foydalanuvchi nomini o'zgartirishga harakat qilaylik. Keling, foydalanuvchilar jadvalini tozalaymiz va kodni ishga tushiramiz
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);
}
}
Ishlaydi! Agar foydalanuvchini o'chirib tashlasangiz nima bo'ladi? Keling, foydalanuvchilar jadvalini tozalaymiz (avtomatiklar o'zini o'zi tozalaydi) va kodni bajaramiz
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);
}
}
Va bizning jadvallarimiz butunlay bo'sh (konsolga e'tibor bering, Hibernate bajargan barcha so'rovlar u erda ko'rsatiladi). Siz ilova bilan o'ynashingiz va uning barcha xususiyatlarini sinab ko'rishingiz mumkin. Masalan, mashinalari bo'lgan foydalanuvchi yarating, uni ma'lumotlar bazasida saqlang, unga qanday identifikator tayinlanganligini ko'ring va main()
ushbu identifikator orqali foydalanuvchini ma'lumotlar bazasidan "tortib olish" usulidan foydalanib ko'ring va konsolda uning mashinalari ro'yxatini ko'rsating. . Albatta, biz Hibernate funksiyasining faqat kichik bir qismini ko'rdik. Uning imkoniyatlari juda keng va u uzoq vaqtdan beri Java rivojlanishi uchun sanoat standartlaridan biri bo'lib kelgan. Agar siz uni batafsil o'rganmoqchi bo'lsangiz, men oldingi maqolalarimdan birida ko'rib chiqqan "Java Persistence API and Hibernate" kitobini tavsiya qilishim mumkin. Umid qilamanki, ushbu maqola o'quvchilar uchun foydali bo'ldi. Agar sizda biron bir savol bo'lsa, ularni sharhlarda so'rang, men mamnuniyat bilan javob beraman :) Shuningdek, muallifni tanlovda "Like" orqali qo'llab-quvvatlashni unutmang. Yoki yaxshiroq - "Menga juda yoqadi" :) O'qishlaringizga omad!
GO TO FULL VERSION