Бұл мақалада сіз Java үшін ең танымал кәсіпорын шеңберлерінің бірімен танысасыз және Hibernate арқылы бірінші қолданбаңызды жасайсыз. Гибернация туралы ешқашан естіген жоқсыз ба? Мүмкін сіз бұл туралы естіген шығарсыз, бірақ оны пайдаланбаған шығарсыз? Немесе бастауға тырысты, бірақ сәтсіз болды ма? Үш жағдайда да кесуге қош келдіңіз :) Барлығына сәлем! Бұл мақалада мен күту режимінің негізгі мүмкіндіктері туралы сөйлесемін және бірінші шағын қолданбаны жазуға көмектесемін. Ол үшін бізге қажет:
Енді Java codeына көшейік. Жоба үшін барлық қажетті пакеттер мен сыныптарды жасаңыз. Бастау үшін бізге деректер үлгілері қажет болады - сыныптар
- Intellij Idea Ultimate Edition; Ресми веб-сайттан
жүктеп алыңыз және 30 күндік сынақ нұсқасын іске қосыңыз. - PostgeSQL – ең танымал заманауи мәліметтер қорын басқару жүйелерінің (ДҚБЖ) бірі;
- Maven (IDEA-ға қазірдің өзінде енгізілген);
- Кішкене шыдамдылық.
Күту күйі дегеніміз не?
Бұл ORM моделінің ең танымал іске асыруларының бірі. Объектілік реляциялық модель программалық an objectілер мен деректер қорындағы жазбалар арасындағы байланыстарды сипаттайды. Әрине, Hibernate функциясының мүмкіндіктері өте кең, бірақ біз ең қарапайым функцияларға тоқталамыз. Біздің мақсатымыз: CRUD қолданбасын жасау (Жасау, Оқу, Жаңарту, Жою), ол:- Пайдаланушыларды (Пайдаланушы) жасаңыз, сондай-ақ оларды дерекқорда идентификатор бойынша іздеңіз, олардың дерекқордағы деректерін жаңартыңыз, сонымен қатар оларды дерекқордан жойыңыз.
- Пайдаланушыларға көлік an objectілерін (Авто) тағайындаңыз. Дерекқордан көліктерді жасаңыз, өңдеңіз, табыңыз және жойыңыз.
- Сонымен қатар, қолданба дерекқордан «жетім» көліктерді автоматты түрде алып тастауы керек. Анау. Пайдаланушы жойылған кезде оған тиесілі барлық көліктер де дерекқордан жойылуы керек.
com.вашНикнейм.javarush
, бұл қолданбаның жұмысына ешқандай әсер етпейді. ArtifactId үшін өзіңізге ұнайтын кез келген жоба атауын таңдаңыз. Сондай-ақ Нұсқаны өзгеріссіз қалдыра аласыз. Соңғы экранда бұрын енгізілген деректерді растаңыз. Сонымен, біз жобаны жасадық, codeты жазып, оны жұмыс істеуге қалдыру ғана қалады :) Біріншіден, егер біз мәліметтер қорымен жұмыс істейтін қосымшаны жасағымыз келсе, онда біз міндетті түрде дерекқорсыз істей алмаймыз! PostgreSQL-ті осы жерден жүктеп алыңыз (мен 9 нұсқасын қолданамын). PostgreSQL-де әдепкі пайдаланушы «postgres» бар, орнату кезінде оған құпия сөз жасау қажет. Құпия сөзіңізді ұмытпаңыз, ол бізге кейінірек қажет болады! (Жалпы, қолданбаларда әдепкі дерекқорды пайдалану жаман тәжірибе, бірақ геморрой санын азайту үшін біз өз дерекқорымызды жасаумен айналысамыз). Пәрмен жолы мен SQL сұраулары сізге ыңғайсыз болса, жақсы жаңалық бар. Intellij IDEA дерекқормен жұмыс істеу үшін өте қолайлы пайдаланушы интерфейсін ұсынады. Бұл келесідей көрінеді: (IDEA оң жақ бүйірлік тақтасында, Дерекқор қойындысында орналасқан) Қосылым жасау үшін «+» түймесін басып, провайдерді (PostgeSQL) таңдаңыз. Пайдаланушы, дерекқор атауы (екеуі де postgres) бар өрістерді толтырыңыз және PostgreSQL орнату кезінде орнатқан құпия сөзді енгізіңіз. Қажет болса, Postgres драйверін жүктеп алыңыз, мұны дәл осы бетте жасауға болады. Дерекқорға қосылым орнатылғанын тексеру үшін «Қосылымды тексеру» түймесін басыңыз. Егер сіз «Сәтті» деген жазуды көрсеңіз, біз жалғастырамыз. Енді бізге қажетті кестелерді құрайық. Олардың екеуі болады - пайдаланушылар мен автолар. Пайдаланушылар кестесіне арналған параметрлер: id негізгі кілт екенін ескеріңіз. SQL-де негізгі кілттің не екенін білмесеңіз, оны Google-да іздеңіз, бұл маңызды. Автокөлік кестесі үшін параметр: Автокөліктер үшін сыртқы кілт - сыртқы кілтті конфигурациялау қажет. Ол біздің кестелерімізді байланыстырады. Мен сізге ол туралы көбірек оқуға кеңес беремін; Қарапайым тілмен айтқанда, ол сыртқы кестеге, біздің жағдайда пайдаланушыларға қатысты. Егер автомобиль id=1 пайдаланушыға тиесілі болса, онда autos кестесінің user_id өрісінде 1 болады. Қолданбамызда пайдаланушыларды көліктерімен осылай байланыстырамыз. Біздің autos кестесінде user_id өрісі сыртқы кілт ретінде қызмет етеді. Ол пайдаланушылар кестесінің идентификатор өрісіне сілтеме жасайды. Осылайша, біз екі кестеден тұратын мәліметтер қорын жасадық. Оны Java codeынан қалай басқаруға болатынын түсіну қалады. Біз pom.xml файлынан бастаймыз, оған қажетті кітапханаларды қосу керек (Maven тілінде олар тәуелділіктер деп аталады). Барлық кітапханалар орталық Maven репозиторийінде сақталады. Олардың сіз pom.xml ішінде көрсеткендерін жобада пайдалана аласыз. Сіздің pom.xml келесідей болуы керек: Көріп отырғаныңыздай күрделі ештеңе жоқ. Біз тек 2 тәуелділікті қостық - PostgreSQL және Hibernate пайдалану үшін.
User
және 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;
}
}
Көріп отырғаныңыздай, сыныптар әлі де түсініксіз annotationлармен жабдықталған. Олармен айналысуды бастайық. Біз үшін негізгі annotation - @Entity. Бұл туралы Википедиядан оқып, бәрін есте сақтаңыз, бұл негіздердің негізі. Бұл annotation сыныптың Java нысандарын дерекқормен байланыстыруға мүмкіндік береді. Сынып субъекті болуы үшін ол келесі талаптарға сай болуы керек:
- Бос конструктор болуы керек (
public
немесеprotected
); - Кірістірілген, интерфейс немесе мүмкін емес
enum
; - -өрістері/қасиеттері бола алмайды
final
және қамтуы мүмкін емес ;final
- Кемінде бір @Id өрісі болуы керек.
- Құрамында бос емес конструкторлар;
- Мұрагерлік және мұрагер болу;
- Басқа әдістерді қамтиды және интерфейстерді іске қосыңыз.
User
пайдаланушылар кестесіне өте ұқсас. өрістер бар id
, name
, age
. Олардың үстінде орналасқан annotationлар көп түсіндіруді қажет етпейді: @Id өрістің осы класс нысандарының идентификаторы болып табылатынының көрсеткіші екені қазірдің өзінде анық. Сынып үстіндегі @Table annotationсы нысандар жазылатын кестенің атын көрсетеді. Жас өрісінің үстіндегі түсініктемеге назар аударыңыз: сыныптағы өріс атауы мен кесте бірдей болса, @Column annotationсын қосудың қажеті жоқ, ол осылай жұмыс істейді. Жақшада көрсетілген «стратегия = GenerationType.IDENTITY» бойынша: бірнеше ID генерациялау стратегиялары бар. Сіз оны google-де іздей аласыз, бірақ біздің қолданба аясында сізге алаңдаудың қажеті жоқ. Ең бастысы, біздің нысандардың идентификаторлары автоматты түрде жасалады, сондықтан идентификатор үшін орнатушы жоқ және оны конструкторда да көрсетпейміз. Дегенмен, сынып әлі де кейбір жағынан User
ерекшеленеді . Оның көліктер тізімі бар! @OneToMany annotationсы тізімнің үстінде пайда болады. Бұл пайдаланушы класының бір an objectісі бірнеше машиналарға сәйкес келетінін білдіреді. "mappedBY" параметрі сыныптың пайдаланушы өрісіне нұсқайды Auto
. Осылайша, машиналар мен пайдаланушылар бір-бірімен байланысады. orphanRemoval параметрі ағылшын тілінен өте жақсы аударылады - «жетімдерді жою». Егер пайдаланушыны дерекқордан жойсақ, онымен байланысты барлық көліктер де жойылады. Өз кезегінде, сыныпта Auto
сіз @ManyToOne annotationсымен (көптеген Автоматтар бір Пайдаланушыға сәйкес келуі мүмкін) және @JoinColumn annotationсымен пайдаланушы өрісін көресіз. Ол пайдаланушылар кестесімен байланыс autos кестесіндегі қай баған арқылы болатынын көрсетеді (бұрын біз айтқан сыртқы кілт). Деректер үлгісін жасағаннан кейін, біздің бағдарламамызды дерекқордағы осы деректермен операцияларды орындауға үйрету уақыты келді. HibernateSessionFactoryUtil утorта класынан бастайық. Оның бір ғана міндеті бар – біздің қосымшамыз үшін дерекқормен жұмыс істеу үшін сеанс зауытын жасау (сәлеметсіз бе, «Зауыт!» үлгісі). Басқа ештеңе істей алмайды.
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;
}
}
Бұл сыныпта біз жаңа конфигурация нысанын, Configuration жасаймыз және оған нысандар ретінде қабылдауы керек сыныптарды береміз - User
және Auto
. Әдіске назар аударыңыз configuration.getProperties()
. Тағы қандай қасиеттер? Қайда? Сипаттар - hibernate.cfg.xml арнайы файлында көрсетілген күту күйінің жұмыс істеу параметрлері. Hibernate.cfg.xml мына жерден оқылады: new Configuration().configure();
Көріп отырғаныңыздай, онда ерекше ештеңе жоқ - дерекқорға қосылу параметрлері және show_sql арнайы параметрі. Бұл біздің дерекқорға қарсы орындалатын күту күйіндегі барлық SQL сұраулары консольге шығарылуы үшін қажет. Осылайша сіз Hibernate режимінің әр сәтте не істеп жатқанын нақты көресіз және «сиқырлы» әсерден құтыласыз. Енді бізге сынып керек UserDAO
. (Жақсы түрде интерфейстер арқылы бағдарламалау керек - интерфейсті жасап UserDAO
, оны бөлек жүзеге асыру керек UserDAOImpl
, бірақ codeтың көлемін азайту үшін мен оны өткізіп жіберемін. Мұны нақты жобаларда жасамаңыз!). DAO (деректерге қол жеткізу нысаны) ең көп тараған дизайн үлгілерінің бірі, «Деректерге қол жеткізу». Оның мағынасы қарапайым - қолданбада тек деректерге қол жеткізуге жауап беретін қабат жасау, басқа ештеңе жоқ. Дерекқордан деректерді алыңыз, деректерді жаңартыңыз, деректерді жойыңыз - және бәрі де. DAO туралы көбірек оқыңыз; сіз оларды жұмысыңызда үнемі пайдаланасыз. Біздің сынып не істей алады UserDao
? Іс жүзінде, барлық DAO сияқты, ол тек деректермен жұмыс істей алады. Пайдаланушыны идентификатор бойынша табыңыз, оның деректерін жаңартыңыз, оны жойыңыз, дерекқордан барлық пайдаланушылардың тізімін шығарып алыңыз немесе дерекқорға жаңа пайдаланушыны сақтаңыз - бұл оның барлық функционалдығы.
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
бір-біріне ұқсас. Олардың көпшілігінде біз Session Factory арқылы Session нысанын (біздің дерекқорымызға қосылатын сеанс) аламыз, осы сеанс ішінде бір транзакция жасаймыз, қажетті деректерді түрлендіруді орындаймыз, транзакция нәтижесін дерекқорға сақтаймыз және сеансты жабамыз. Көріп отырғаныңыздай, әдістердің өзі өте қарапайым. 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);
}
}
Сервис — бизнес логикасын орындауға жауап беретін қолданбадағы деректер деңгейі. Егер сіздің бағдарламаңызға бизнес логикасын орындау қажет болса, ол оны қызметтер арқылы жасайды. Қызмет өзінің ішінде бар UserDao
және өз әдістерінде 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("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);
}
}
Көріп отырғаныңыздай, пайдаланушылар кестесінің өз жазбасы бар, ал 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("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);
}
}
Жұмыс істейді! Пайдаланушыны жойсаңыз ше? Пайдаланушылар кестесін тазалайық (автоматтар өзін-өзі тазартады) және 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("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);
}
}
Біздің кестелер толығымен бос (консольге назар аударыңыз, күту режимі орындаған барлық сұраулар сонда көрсетіледі). Сіз қолданбамен ойнай аласыз және оның барлық мүмкіндіктерін қолданып көріңіз. Мысалы, машиналары бар пайдаланушыны жасаңыз, оны дерекқорда сақтаңыз, оған қандай идентификатор тағайындалғанын көріңіз және main()
осы идентификатор арқылы пайдаланушыны дерекқордан «суырып алу» әдісін пайдаланып көріңіз және консольде оның машиналарының тізімін көрсетіңіз. . Әрине, біз Hibernate функциясының кішкене бөлігін ғана көрдік. Оның мүмкіндіктері өте кең және ол бұрыннан Java әзірлеуге арналған салалық стандарттардың бірі болып табылады. Егер сіз оны егжей-тегжейлі зерттегіңіз келсе, мен алдыңғы мақалаларымның бірінде қарастырған «Java Persistence API және Hibernate» кітабын ұсына аламын. Бұл мақала оқырмандар үшін пайдалы болды деп үміттенемін. Егер сізде сұрақтар туындаса, оларды түсініктемелерде қойыңыз, мен қуана жауап беремін :) Сондай-ақ, авторды байқауда оған «Лайк» басып қолдау көрсетуді ұмытпаңыз. Немесе жақсырақ - «маған бұл өте ұнайды» :) Оқуларыңызға сәттілік!
GO TO FULL VERSION