CodeGym /Java Blogu /Rastgele /İlk Hazırda Bekleme uygulamanız
John Squirrels
Seviye
San Francisco

İlk Hazırda Bekleme uygulamanız

grupta yayınlandı
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 :) İlk Hazırda Bekleme uygulamanız - 1 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:
  1. IntelliJ IDEA Ultimate Edition Resmi web sitesinden
    indirin ve 30 günlük deneme sürümünü etkinleştirin.
  2. PostgreSQL - en popüler modern veritabanı yönetim sistemlerinden (DBMS) biri
  3. Maven (zaten IDEA'ya bağlı)
  4. Biraz sabır.
Her ihtimale karşı, uygulama kodunu GitHub'a (codegym şubesi) gönderdim . Makale, öncelikle bu teknolojiyle daha önce hiç çalışmamış olanları hedefliyor, bu yüzden kod miktarını en aza indirdim. Başlayalım!

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:
  1. 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.
  2. Kullanıcılara araba nesneleri (Otomatik) atayın. Veritabanından araba oluşturun, güncelleyin, bulun ve silin.
  3. 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.
Projemiz şu şekilde yapılandırılacak: İlk Hazırda Bekleme uygulamanız - 2Gö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. İlk Hazırda Bekleme uygulamanız - 3Apache 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 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. İlk Hazırda Bekleme uygulamanız - 4Son ekranda, daha önce girilen verileri onaylamanız yeterlidir.İlk Hazırda Bekleme uygulamanız - 5Bö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. İlk Hazırda Bekleme uygulamanız - 6(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: İlk Hazırda Bekleme uygulamanız - 7id'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: İlk Hazırda Bekleme uygulamanız - 8autos 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. İlk Hazırda Bekleme uygulamanız - 9Bö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: İlk Hazırda Bekleme uygulamanız - 10Gö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: Userve Autosı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:
  • publicBoş bir oluşturucuya ( veya protected) sahip olmalıdır.
  • İç içe olamaz, bir arayüz veyaenum
  • Alanlar/özellikler olamaz finalve olamazfinal
  • En az bir @Id alanına sahip olmalıdır.
Varlık sınıflarınızı kontrol edin: kendi ayağınıza sıkmak için çok popüler yerlerdir. Bir şeyi unutmak çok kolaydır. Ayrıca, bir varlık aşağıdakileri yapabilir:
  • Boş olmayan oluşturuculara sahip olabilir
  • Miras alınabilir ve miras alınabilir
  • Başka yöntemlere sahip olabilir ve arabirimleri uygulayabilir.
Gördüğünüz gibi Usersınıf, users tablosuna çok benzer. id, ve name_agealanlar. Ü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,Usersınıf öne çıkıyor. Arabaların bir listesi var! İlk Hazırda Bekleme uygulamanız - 11@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 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çindeAutosı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: Userve 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. İlk Hazırda Bekleme uygulamanız - 12Hibernate.cfg.xml burada okunur: 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 varUserDAOsınıf. En iyi uygulama, arabirimler aracılığıyla programlama yapmaktır — ayrı bir UserDAOarabirim ve UserDAOImpluygulama 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;
     }
 }
 
UserDaoyö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 UserDaove 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. İlk Hazırda Bekleme uygulamanız - 13İlk Hazırda Bekleme uygulamanız - 14Kullanıcımızı yeniden adlandırmayı deneyelim. users tablosunu temizleyin ve kodu çalıştırın

 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! İlk Hazırda Bekleme uygulamanız - 15Kullanıcıyı silerseniz ne olur? Kullanıcılar tablosunu temizleyin (otomatikler kendi kendini temizler) ve kodu yürütün

 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!
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION