Bu makalede, Java için en popüler kurumsal çerçevelerden birini tanıyacak ve ilk Hibernate uygulamanızı oluşturacaksınız. Hibernate'i hiç duymadın mı? Ya da belki duymuşsunuzdur, ancak kullanmamışsınızdır? Ya da belki kullanmayı denediniz ama başarısız oldunuz? Her üç durumda da - kesimin altına hoş geldiniz :)
Herkese merhaba! Bu yazıda Hibernate çerçevesinin ana özelliklerinden bahsedeceğim ve ilk mini uygulamanızı yazmanıza yardımcı olacağım. Bunun için ihtiyacımız var:
Gördüğünüz gibi karmaşık bir şey yok. 6 sınıf + yapılandırmalı 1 dosya. İlk olarak, IntelliJ IDEA'da yeni bir Maven projesi oluşturun. Dosya -> Yeni Proje. Önerilen proje türleri arasından Maven'i seçin ve bir sonraki adıma geçin.
Apache Maven, POM dosyalarındaki yapılarının açıklamasına dayalı olarak projeleri otomatik olarak oluşturmak için bir çerçevedir. Projenizin tüm yapısı, IDEA'nın projenizin kökünde oluşturacağı bir dosya olan pom.xml'de açıklanacaktır. Proje ayarlarında, şu Maven ayarlarını belirtmeniz gerekir: groupId ve structureId. Projelerde, groupId genellikle şirketin veya iş biriminin bir açıklamasıdır. Şirketin veya web sitesinin alan adı buraya gelebilir. ArtifactId ise projenin adıdır. groupdId için girebilirsiniz
Son ekranda, daha önce girilen verileri onaylamanız yeterlidir.
Böylece projeyi oluşturduk. Şimdi geriye sadece bir kod yazıp çalışmasını sağlamak kaldı :) İlk önce: Eğer bir veritabanı ile çalışan bir uygulama oluşturmak istiyorsak, kesinlikle veritabanı olmadan yapamayız! PostgreSQL'i buradan indirin ( sürüm 9 kullanıyorum). PostgreSQL'in varsayılan bir kullanıcısı olan 'postgres' vardır — kurarken bunun için bir parola düşünmeniz gerekir. Şifreyi unutma. Daha sonra ihtiyacımız olacak! (Genel olarak, uygulamalarda varsayılan veritabanını kullanmak kötü bir uygulamadır, ancak bunu kendi veritabanınızı oluşturarak ülserlerin neden olduğu sayısını azaltmak için yapacağız). Komut satırı ve SQL sorgularıyla arkadaş değilseniz, iyi haberlerimiz var. IntelliJ IDEA, veritabanıyla çalışmak için tamamen uygun bir kullanıcı arabirimi sağlar.
(IDEA'nın sağ bölmesinde, Veritabanı sekmesinde bulunur). Bir bağlantı oluşturmak için "+"ya tıklayın ve veri kaynağımızı (PostgeSQL) seçin. Kullanıcı ve veritabanı (her ikisi için de "postgres") alanlarını doldurun ve PostgreSQL'in kurulumu sırasında ayarlanan parolayı girin. Gerekirse, Postgres sürücüsünü indirin. Bunu aynı sayfada yapabilirsiniz. Veritabanı bağlantısının kurulduğunu doğrulamak için "Bağlantıyı Test Et" seçeneğine tıklayın. "Başarılı" görürseniz, devam edin. Şimdi ihtiyacımız olan tabloları oluşturacağız. Toplam iki tane olacak: kullanıcılar ve otomobiller. Kullanıcılar tablosu için parametreler:
id'nin birincil anahtar olduğunu unutmayın. SQL'de birincil anahtarın ne olduğunu bilmiyorsanız, Google'da arayın. Bu önemli. Otomobil tablosu için ayarlar:
autos tablosu için bir yabancı anahtar yapılandırmanız gerekir. Tablolarımızı birbirine bağlamaya hizmet edecek. Bu konuda daha fazla okumanızı tavsiye ederim. Basitçe söylemek gerekirse, bizim durumumuzda kullanıcılar olan harici bir tabloya başvurur. Eğer bir araba id=1 olan kullanıcıya ait ise o zaman arabaların user_id alanı 1 olacaktır. Uygulamamızda kullanıcıları arabaları ile bu şekilde ilişkilendiriyoruz. autos tablomuzda user_id alanı yabancı anahtar olarak işlev görecektir. Users tablosunun id alanına atıfta bulunacaktır.
Böylece iki tablolu bir veritabanı oluşturduk. Geriye kalan, onu Java kodundan nasıl yöneteceğinizi anlamaktır. Gerekli kitaplıkları dahil etmemiz gereken pom.xml dosyasıyla başlayacağız (Maven'de bunlara bağımlılıklar denir). Tüm kütüphaneler, merkezi Maven deposunda saklanır. Pom.xml'de belirttiğiniz kütüphaneler projede kullanmanız için hazırdır. Pom.xml dosyanız şöyle görünmelidir:
Gördüğünüz gibi karmaşık bir şey yok. PostgreSQL ve Hibernate'i kullanmak için yalnızca 2 bağımlılık ekledik. Şimdi Java koduna geçelim. Projede gerekli tüm paketleri ve sınıfları oluşturun. Başlamak için bir veri modeline ihtiyacımız var:
@OneToMany ek açıklaması listenin üzerinde asılı kalıyor. Bu, birkaç arabanın User sınıfının aynı nesnesine karşılık gelebileceği anlamına gelir. "mappedBy" öğesi, sınıfın kullanıcı alanını ifade eder
Hibernate.cfg.xml burada okunur: ![İlk Hazırda Bekleme uygulamanız - 13]()
Kullanıcımızı yeniden adlandırmayı deneyelim. users tablosunu temizleyin ve kodu çalıştırın
Kullanıcıyı silerseniz ne olur? Kullanıcılar tablosunu temizleyin (otomatikler kendi kendini temizler) ve kodu yürütün

- IntelliJ IDEA Ultimate Edition Resmi web sitesinden
indirin ve 30 günlük deneme sürümünü etkinleştirin. - PostgreSQL - en popüler modern veritabanı yönetim sistemlerinden (DBMS) biri
- Maven (zaten IDEA'ya bağlı)
- Biraz sabır.
Hazırda bekletme nedir?
En popüler nesne ilişkisel eşleme (ORM) uygulamalarından biridir. Nesne-ilişkisel eşleme, yazılım nesneleri ile veritabanı kayıtları arasındaki ilişkiyi tanımlar. Elbette Hazırda Bekletme çok geniş bir işlevselliğe sahiptir, ancak en basit işlevlere odaklanacağız. Amacımız, şunları yapabilecek bir CRUD (Oluştur, Oku, Güncelle, Sil) uygulaması oluşturmaktır:- Kullanıcılar (Kullanıcı) oluşturun, bunları veritabanında kimliğe göre arayın, veritabanındaki verilerini güncelleyin ve bunları veritabanından silin.
- Kullanıcılara araba nesneleri (Otomatik) atayın. Veritabanından araba oluşturun, güncelleyin, bulun ve silin.
- Ek olarak, uygulama "sahipsiz" arabaları veritabanından otomatik olarak kaldırmalıdır. Yani bir kullanıcı silindiğinde o kullanıcıya ait tüm arabaların da veri tabanından silinmesi gerekiyor.


com.yourNickname.codegym
. Bunun uygulama üzerinde herhangi bir etkisi olmayacaktır. artifactId için istediğiniz herhangi bir proje adını seçin. Sürüm değişmeden bırakılabilir. 






User
ve Auto
sınıfları.
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;
}
}
Gördüğünüz gibi, sınıflar bir sürü anlaşılmaz açıklama içeriyor. Onları kazmaya başlayalım. Bizim için ana ek açıklama @Entity'dir. Wikipedia'da bunun hakkında okuyun ve hepsini ezbere öğrenin. Bu vakfın temelidir. Bu ek açıklama, Java sınıfınızın nesnelerinin bir veritabanına eşlenmesini sağlar. Bir sınıfın varlık olabilmesi için aşağıdaki gereksinimleri karşılaması gerekir:
public
Boş bir oluşturucuya ( veyaprotected
) sahip olmalıdır.- İç içe olamaz, bir arayüz veya
enum
- Alanlar/özellikler olamaz
final
ve olamazfinal
- En az bir @Id alanına sahip olmalıdır.
- Boş olmayan oluşturuculara sahip olabilir
- Miras alınabilir ve miras alınabilir
- Başka yöntemlere sahip olabilir ve arabirimleri uygulayabilir.
User
sınıf, users tablosuna çok benzer. id
, ve name
_age
alanlar. Üstlerinde yer alan açıklamaların herhangi bir özel açıklamaya ihtiyacı yoktur: @Id'nin, alanın bu sınıftaki nesnelerin tanımlayıcısı olduğunu gösterdiği açıktır. Sınıfın üzerindeki @Table ek açıklaması, nesnelerin yazıldığı tablonun adını gösterir. Yaş alanının üstündeki yoruma dikkat edin: sınıftaki alanın adı tablonun adıyla aynıysa, @Column ek açıklamasını atlayabilirsiniz ve çalışacaktır. Köşeli ayraçlar içinde belirtilen kısımla ilgili olarak ("strategy = GenerationType.IDENTITY"): kimlik oluşturmak için çeşitli stratejiler vardır. Bunları Google'da arayabilirsiniz, ancak bizim uygulamamız için zahmet etmenize gerek yok. Ana şey, nesnelerimiz için id değerinin otomatik olarak üretilecek olmasıdır. Buna göre, id için ayarlayıcı yoktur ve onu yapıcıda da ayarlamayız. Fakat,User
sınıf öne çıkıyor. Arabaların bir listesi var! 
Auto
. Böylece, arabalar ve kullanıcılar ilişkilidir. yetimRemoval öğesi, kaldırma işleminin artık bir ilişkisi olmayan varlıklara uygulanıp uygulanmayacağını belirtir. Bir kullanıcıyı veri tabanından silersek, onunla ilişkili tüm arabalar da silinir. sırayla, içindeAuto
sınıfında, @ManyToOne notu (bir Kullanıcı birçok Auto'ya karşılık gelebilir) ve @JoinColumn notu ile kullanıcı alanını göreceksiniz. Kullanıcılar tablosuna (yani daha önce bahsettiğimiz yabancı anahtar) başvurmak için autos tablosundaki hangi sütunun kullanıldığını gösterir. Veri modelini oluşturduktan sonra, programımıza veri tabanındaki verilerle işlem yapmasını öğretme zamanı. HibernateSessionFactoryUtil yardımcı programı sınıfıyla başlayalım. Tek bir görevi vardır — uygulamamızın veri tabanıyla çalışması için bir oturum fabrikası oluşturmak (Fabrika tasarım modeline merhaba deyin!). Başka bir şey yapmayı bilmiyor.
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;
}
}
Bu sınıfta, yeni bir Configuration nesnesi oluşturuyoruz ve ona varlık olarak işlemesi gereken sınıfları iletiyoruz: User
ve Auto
. Yönteme dikkat edin configuration.getProperties()
. Başka hangi özellikler var? Nerden geliyorlar? Özellikler, özel hibernate.cfg.xml dosyasında belirtilen hazırda bekletme ayarlarıdır. 
new Configuration().configure();
Gördüğünüz gibi, bunda özel bir şey yok: show_sql parametresinin yanı sıra veritabanına bağlanmak için parametreler içeriyor. Hibernate tarafından yürütülen tüm sql sorgularının konsolda görüntülenmesi için bu gereklidir. Bu şekilde, Hibernate'in herhangi bir anda ne yaptığını tam olarak görerek herhangi bir "sihir" duygusunu ortadan kaldırmış olursunuz. Sonra ihtiyacımız varUserDAO
sınıf. En iyi uygulama, arabirimler aracılığıyla programlama yapmaktır — ayrı bir UserDAO
arabirim ve UserDAOImpl
uygulama oluşturun, ancak kod miktarını azaltmak için bunu atlayacağım. Bunu gerçek projelerde yapmayın! DAO (veri erişim nesnesi) tasarım modeli en yaygın olanlardan biridir. Fikir basit — yalnızca verilere erişimden sorumlu bir uygulama katmanı oluşturun, başka bir şey değil. Veritabanından veri alın, verileri güncelleyin, verileri silin - hepsi bu. DAO hakkında daha fazla çalışın. İşinizde sürekli olarak veri erişim nesnelerini kullanacaksınız. Sınıfımız ne yapabilir UserDao
? Tüm DAO'lar gibi, yalnızca verilerle çalışabilir. Kimliğine göre bir kullanıcı bulun, verilerini güncelleyin, silin, veritabanındaki tüm kullanıcıların bir listesini alın veya veritabanına yeni bir kullanıcı kaydedin — işlevselliğinin tamamı budur.
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
yöntemleri birbirine benzer. Çoğunda Session Factory'mizi kullanarak bir Session nesnesi (veritabanı bağlantı oturumu) alırız, bu oturum içerisinde tek bir işlem oluşturur, gerekli veri işlemlerini gerçekleştirir, işlem sonucunu veritabanına kaydeder ve ardından oturumu kapatırız. Gördüğünüz gibi yöntemlerin kendisi oldukça basit. DAO, uygulamamızın "kalbidir". Ancak, doğrudan bir DAO oluşturup, yöntemimizde onun yöntemlerini çağırmayacağız main()
. Tüm mantık sınıfa taşınacaktır 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);
}
}
Hizmet, iş mantığını yürütmekten sorumlu bir uygulama veri katmanıdır. Programınızın bir tür iş mantığı yürütmesi gerekiyorsa, bunu hizmetler aracılığıyla yapar. Bir hizmet a içerir UserDao
ve yöntemlerinde DAO yöntemlerini çağırır. Burada işlevleri çoğaltıyormuşuz gibi görünebilir (neden yöntemleri bir DAO nesnesinden çağırmıyoruz?), ancak çok sayıda nesne ve karmaşık mantıkla, uygulamayı katmanlamak çok büyük avantajlar sağlar (bunu yapmak iyi bir uygulamadır - bunu gelecekte unutmayın) ve "uygulama katmanları" hakkında okuyun). Hizmetimiz basit bir mantığa sahiptir, ancak gerçek dünya projelerindeki hizmet yöntemleri birden fazla kod satırı içerir :) Artık uygulamayı çalıştırmak için ihtiyacınız olan her şeye sahibiz! Yöntemde main()
bir kullanıcı ve arabası oluşturalım, birbiriyle ilişkilendirelim ve veritabanına kaydedelim.
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);
}
}
Gördüğünüz gibi users tablosunun kendi kaydı, autos tablosunun da kendi kaydı var. 

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);
}
}
İşe yarıyor! 
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);
}
}
Ve tablolarımız tamamen boş (konsola dikkat edin - Hibernate tarafından gerçekleştirilen tüm istekler burada görüntülenecektir). Uygulama ile oynayabilir ve tüm işlevlerini deneyebilirsiniz. Örneğin, arabaları olan bir kullanıcı oluşturun, onu veritabanına kaydedin, kullanıcıya atanan kimliğe bakın ve bu kimliği arabalarda kullanmayı deneyin.main()
kullanıcıyı veri tabanından getirme ve konsolda arabalarının bir listesini görüntüleme yöntemi. Tabii ki, Hibernate'in işlevselliğinin sadece küçük bir kısmını gördük. Yetenekleri çok geniştir ve uzun süredir Java geliştirme için standart bir endüstri aracı olmuştur. Detaylı incelemek isterseniz "Java Persistence API and Hibernate" kitabını tavsiye edebilirim. Önceki bir makalede inceledim. Umarım bu makale okuyuculara yardımcı olmuştur. Sorularınız varsa, yorumlarda sorun. Cevaplamaktan mutluluk duyarım :) Ayrıca, "Beğen" yazarak yarışmada yazara destek olmayı unutmayın. Ya da daha iyisi - "Beğendim" :) Çalışmalarınızda bol şans!
GO TO FULL VERSION