CodeGym /Java блог /Случаен /Вашето първо приложение за хибернация
John Squirrels
Ниво
San Francisco

Вашето първо приложение за хибернация

Публикувано в групата
В тази статия ще се запознаете с една от най-популярните корпоративни рамки за Java и ще създадете първото си приложение Hibernate. Никога не сте чували за Hibernate? Или може би сте чували за него, но не сте го използвали? Или може би сте се опитали да го използвате, но неуспешно? И в трите случая - добре дошли в under the cut :) Вашето първо приложение Hibernate - 1 Здравейте на всички! В тази статия ще говоря за основните характеристики на рамката Hibernate и ще ви помогна да напишете първото си мини-приложение. За целта се нуждаем от:
  1. IntelliJ IDEA Ultimate Edition
    Изтеглете го от официалния уебсайт и активирайте 30-дневната пробна version.
  2. PostgreSQL - една от най-популярните съвременни системи за управление на бази данни (СУБД)
  3. Maven (вече е свързан към IDEA)
  4. Малко търпение.
За всеки случай публикувах codeа на приложението в GitHub (codegym клон). Статията е насочена предимно към тези, които никога преди не са работor с тази технология, така че минимизирах количеството code. Да започваме!

Какво е Hibernate?

Това е една от най-популярните реализации на обектно-релационно картографиране (ORM). Обектно-релационното съпоставяне дефинира връзката между софтуерните обекти и записите в базата данни. Разбира се, Hibernate има много широка функционалност, но ние ще се съсредоточим върху най-простите функции. Нашата цел е да създадем CRUD (Създаване, четене, актуализиране, изтриване) приложение, което ще може:
  1. Създавайте потребители (User), търсете ги в базата данни по ID, актуализирайте данните им в базата данни и ги изтривайте от базата данни.
  2. Присвояване на автомобилни обекти (Авто) на потребителите. Създавайте, актуализирайте, намирайте и изтривайте автомобor от базата данни.
  3. Освен това приложението трябва автоматично да премахва "безстопанствените" автомобor от базата данни. С други думи, когато даден потребител бъде изтрит, всички автомобor, принадлежащи на този потребител, също трябва да бъдат изтрити от базата данни.
Нашият проект ще бъде структуриран по следния начин: Вашето първо приложение Hibernate - 2Както виждате, нищо сложно. 6 класа + 1 файл с конфигурации. Първо създайте нов проект на Maven в IntelliJ IDEA. Файл -> Нов проект. Изберете Maven от предложените типове проекти и преминете към следващата стъпка. Вашето първо приложение Hibernate - 3Apache Maven е рамка за автоматично изграждане на проекти въз основа на описание на тяхната структура в POM файлове. Цялата структура на вашия проект ще бъде описана в pom.xml, файл, който самата IDEA ще създаде в корена на вашия проект. В настройките на проекта трябва да зададете следните настройки на Maven: groupId и artifactId. В проекти groupId обикновено е описание на компанията or бизнес единицата. Името на домейна на компанията or уебсайта може да отиде тук. От своя страна artifactId е името на проекта. За groupdId можете да въведете com.yourNickname.codegym. Това няма да има ефект върху приложението. За artifactId изберете произволно име на проект, което харесвате. Версията може да остане непроменена. Вашето първо приложение Hibernate - 4На последния екран просто потвърдете въведените преди това данни.Вашето първо приложение Hibernate - 5И така, създадохме проекта. Сега всичко, което остава да направите, е да напишете малко code и да го накарате да работи :) Първо: ако искаме да създадем приложение, което работи с база данни, определено не можем без база данни! Изтеглете PostgreSQL от тук (използвам version 9). PostgreSQL има потребител по подразбиране 'postgres' — ще трябва да измислите парола за него, когато инсталирате. Не забравяйте паролата. Ще ни трябва по-късно! (По принцип използването на базата данни по подразбиране в applicationsта е лоша практика, но ние ще го направим, за да намалим броя на причините за язви, като създадем ваша собствена база данни). Ако не сте приятели с командния ред и SQL заявките, има добри новини. IntelliJ IDEA предоставя напълно подходящ потребителски интерфейс за работа с базата данни. Вашето първо приложение Hibernate - 6(разположен в десния панел на IDEA, раздел База данни). За да създадете връзка, щракнете върху „+“ и изберете нашия източник на данни (PostgeSQL). Попълнете полетата за потребителя и базата данни ("postgres" и за двете) и въведете паролата, зададена по време на инсталирането на PostgreSQL. Ако е необходимо, изтеглете драйвера на Postgres. Можете да направите това на същата page. Щракнете върху „Тест на връзката“, за да проверите дали връзката с базата данни е установена. Ако видите „Успешно“, продължете напред. Сега ще създадем таблиците, от които се нуждаем. Ще има общо две: потребители и автомобor. Параметри за tableта потребители: Вашето първо приложение Hibernate - 7Обърнете внимание, че id е първичният ключ. Ако не знаете Howъв е първичният ключ в SQL, потърсете го в Google. Това е важно. Настройки за tableта с автомати: Вашето първо приложение Hibernate - 8За tableта autos трябва да конфигурирате външен ключ. Той ще служи за свързване на нашите маси. Препоръчвам ви да прочетете повече за това. Казано по-просто, той препраща към външна table, в нашия случай потребители. Ако кола принадлежи на потребител с id = 1, тогава полето user_id на автомобorте ще бъде равно на 1. Това е начинът, по който свързваме потребителите с техните автомобor в нашето приложение. В нашата table autos полето user_id ще действа като външен ключ. Той ще препраща към полето за идентификатор на tableта с потребители. Вашето първо приложение Hibernate - 9И така, създадохме база данни с две таблици. Остава да разберем How да го управляваме от Java code. Ще започнем с file pom.xml, в който трябва да включим необходимите библиотеки (в Maven те се наричат ​​dependencies). Всички библиотеки се съхраняват в централното хранorще на Maven. Библиотеките, които посочите в pom.xml, са достъпни за използване в проекта. Вашият pom.xml трябва да изглежда така: Вашето първо приложение за Hibernate - 10Нищо сложно, Howто виждате. Добавихме само 2 зависимости — за използване на PostgreSQL и Hibernate. Сега нека да преминем към Java codeа. Създайте всички необходими пакети и класове в проекта. За да започнем, имаме нужда от модел на данни: класовете Userand 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 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;
     }
 }
 
 
Както можете да видите, класовете имат куп неясни анотации. Нека започнем да се ровим в тях. За нас основната анотация е @Entity. Прочетете за това в Wikipedia и го научете всичко наизуст. Това е основата на основата. Тази анотация позволява обекти от вашия Java клас да бъдат картографирани към база данни. За да бъде един клас обект, той трябва да отговаря на следните изисквания:
  • Трябва да има празен конструктор ( publicor protected)
  • Не може да бъде вложен, интерфейс orenum
  • Не може да бъде finalи не може да има finalполета/свойства
  • Трябва да има поне едно поле @Id.
Проверете вашите класове на обекти: те са много популярни места, където да се простреляте в крака. Много е лесно да забравиш нещо. Освен това дадено предприятие може да направи следното:
  • Може да има непразни конструктори
  • Може да се наследява и да се наследява
  • Може да има други методи и да реализира интерфейси.
Както можете да видите, Userкласът е много подобен на tableта на потребителите. Има id, name, иageполета. Анотациите, разположени над тях, не се нуждаят от специално обяснение: ясно е, че @Id показва, че полето е идентификатор на обекти от този клас. Анотацията @Table над класа показва името на tableта, където са записани обектите. Обърнете внимание на коментара над полето за възраст: ако името на полето в класа е същото като името на tableта, можете да пропуснете анотацията @Column и тя ще работи. Що се отнася до частта, посочена в скобите ("strategy = GenerationType.IDENTITY"): има няколко стратегии за генериране на идентификатори. Можете да ги Google, но за нашето приложение, няма нужда да се притеснявате. Основното е, че за нашите обекти стойността на id ще се генерира автоматично. Съответно няма настройка за id и не го задаваме и в конструктора. Въпреки това,Userкласът се откроява. Има списък с автомобor! Вашето първо приложение Hibernate - 11Анотацията @OneToMany виси над списъка. Това означава, че няколко коли могат да съответстват на един и същ обект от класа User. Елементът "mappedBy" се отнася до потребителското поле на Autoкласа. По този начин автомобorте и потребителите са свързани. Елементът orphanRemoval показва дали да се приложи операцията за премахване към обекти, които вече нямат връзка. Ако изтрием потребител от базата данни, всички автомобor, свързани с него, също ще бъдат изтрити. На свой ред вAutoклас, ще видите потребителското поле с анотацията @ManyToOne (един потребител може да съответства на много Autos) и анотацията @JoinColumn. Той показва коя колона в tableта autos се използва за препратка към tableта потребители (т.е. чуждия ключ, за който говорихме по-рано). След като създадем модела на данни, е време да научим нашата програма да извършва операции с данните в базата данни. Нека започнем с помощния клас HibernateSessionFactoryUtil. Той има само една задача — да създаде фабрика за сесии за нашето приложение, за да работи с базата данни (кажи здравей на шаблона за проектиране Factory!). То не знае How да прави нищо друго.

 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;
     }
 }
 
В този клас създаваме нов конфигурационен обект и му предаваме класовете, които трябва да третира като обекти: Userи Auto. Обърнете внимание на configuration.getProperties()метода. Какви други имоти има? Откъде идват? Свойствата са настройките за хибернация, посочени в специалния файл hibernate.cfg.xml. Вашето първо приложение Hibernate - 12Hibernate.cfg.xml се чете тук: new Configuration().configure(); Както виждате, в него няма нищо особено: той съдържа параметрите за свързване към базата данни, Howто и параметъра show_sql. Това е необходимо, така че всички sql заявки, изпълнени от Hibernate, да се показват на конзолата. По този начин ще видите точно Howво прави Hibernate във всеки един момент, елиминирайки всяHowво усещане за "магия". След това се нуждаем отUserDAOклас. Най-добрата практика е да програмирате чрез интерфейсите — създайте отделен UserDAOинтерфейс и UserDAOImplреализация, но ще пропусна това, за да намаля количеството code. Не правете това в реални проекти! Шаблонът за проектиране DAO (обект за достъп до данни) е един от най-често срещаните. Идеята е проста - създайте приложен слой, отговорен само за достъп до данни, нищо повече. Извличане на данни от базата данни, актуализиране на данни, изтриване на данни — това е всичко. Проучете повече за DAO. Ще използвате постоянно обекти за достъп до данни в работата си. Какво може да направи нашият UserDaoклас? Е, Howто всички DAO, той може да работи само с данни. Намерете потребител по id, актуализирайте данните му, изтрийте го, вземете списък с всички потребители от базата данни or запишете нов потребител в базата данни — това е цялата му функционалност.

 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Методите на са подобни един на друг. В повечето от тях получаваме обект на сесия (сесия за връзка с базата данни), използвайки нашата фабрика за сесии, създаваме една транзакция в рамките на тази сесия, извършваме необходимите манипулации с данни, запазваме резултата от транзакцията в базата данни и след това затваряме сесията. Самите методи, Howто можете да видите, са доста прости. DAO е „сърцето“ на нашето приложение. Ние обаче няма да създаваме директно DAO и да извикваме неговите методи в нашия main()метод. Цялата логика ще бъде преместена в 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);
     }
 
 
 }
 
 
Услугата е слой от данни на приложението, отговорен за изпълнението на бизнес логиката. Ако вашата програма трябва да изпълни няHowва бизнес логика, тя го прави чрез услуги. Услугата съдържа UserDaoи извиква DAO методи в своите методи. Може да изглежда, че дублираме функции тук (защо просто не извикаме методите от DAO обект?), но с много обекти и сложна логика, наслояването на приложението предоставя огромни предимства (да го правите е добра практика – запомнете това в бъдеще и прочетете за "слоеве на приложение"). Нашата услуга има проста логика, но методите на услугата в проекти от реалния свят съдържат много повече от един ред code :) Сега имаме всичко необходимо, за да стартирате приложението! В main()метода нека създадем потребител и неговата кола, да ги асоциираме един с друг и да ги запазим в базата данни.

 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);
     }
 }
 
 
Както можете да видите, tableта users има свой собствен запис, а tableта autos има свой собствен запис. Вашето първо приложение Hibernate - 13Вашето първо приложение Hibernate - 14Нека се опитаме да преименуваме нашия потребител. Изчистете tableта с потребители и изпълнете codeа

 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);
     }
 }
 
 
Работи! Вашето първо приложение Hibernate - 15Ами ако изтриете потребителя? Изчистете tableта с потребители (autos ще се изчисти сама) и изпълнете codeа

 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);
     }
 }
 
 
И нашите таблици са напълно празни (обърнете внимание на конзолата - всички заявки, извършени от Hibernate, ще бъдат показани там). Можете да си поиграете с приложението и да изпробвате всички негови функции. Например, създайте потребител с автомобor, запазете го в базата данни, погледнете идентификатора, присвоен на потребителя, и опитайте да използвате този идентификатор вmain()метод за извличане на потребителя от базата данни и показване на списък с неговите коли на конзолата. Разбира се, видяхме само малка част от функционалността на Hibernate. Неговите възможности са много широки и отдавна е standardн индустриален инструмент за разработка на Java. Ако искате да го проучите подробно, мога да препоръчам книгата "Java Persistence API and Hibernate". Прегледах в предишна статия. Надявам се, че тази статия е била полезна за читателите. Ако имате въпроси, задайте ги в коментарите. Ще се радвам да отговоря :) Освен това не забравяйте да подкрепите автора в конкурса, като публикувате „Харесва ми“. Или още по-добре — „Love it“ :) Успех в обучението!
Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION