Искаме или не, в някакъв момент на нашето приложение му се налага да запише нещо, някъде. Опциите за това не са малко, но въпреки подема в развитието на NoSQL обикновено говорим за релационна база данни.

За кого е този текст?

Моят опит е предимно в Java света, поради което и много от примерите ще бъдат свързани с Java. Въпреки това смятам, че всеки интересуващ се от връзка на своето приложение с базата данни, независимо от езика и използвания framework би намерил нещо полезно и интересно в този пост.

Какво предпочитат програмистите за връзка с базата?

Изследвания и анкети за това какво точно се използва за връзка с базата данни не се правят масово и редовно, но такива съществуват. Нека разгледаме резултатите от две такива, правени преди няколко години във водещ Java уеб портал:

dzone.com survey

dzone.com persistence survey

Данните изглеждат малко различни, но и двете графики показват ясно, че:

  • ORM в лицето на JPA/Hibernate доминира
  • Aлтернативата e директно използване на JDBC, т.е SQL
  • Често се използва повече от една технология – сборът е повече от 100%
  • Другите алтернативи имат много малък дял

ORM или не? JPA/Hibernate или JDBC?

Двете доминиращи възможности са доста различни. Едното е ORM – абстракция, разработена с целта да улесни работата ни с базата. Другото директно вика SQL-a, който му зададем.

И двете имат плюсове и минуси.

Кое е по-добро обикновено зависи от това, какво искаме да постигнем.

JPA/Hibernate – предимства и недостатъци

Предпочитаният начин за връзка с базата в Java света.

Java вместо SQL

Най-голямото предимство и едновременно най-голям недостатък е именно фактът, че не използваме SQL директно.

Вместо да пишем SQL използваме Java код и работим с обекти. Когато искаме да добавим или вземем нещо от базата превръщането между редове в базата към обекти и обратно е улеснено.

Понякога обаче си плащаме и цена за това улеснение. Връзката между обекти в Java и съответните редове в база от данни може да бъде затруднена благодарение на т.нар. Object-relational impedance mismatch. Той обхваща доста голям брой възможни проблеми, но ето някои:

  • Разлики в типа данни
  • Структурни разлики
  • OOP концепции != релационните

Някои от тези разлики се решават по-лесно с ORM отколкото без (като тези с типа данни). Използването на ORM често ги крие от нас, което води до изненади и проблеми.

Друг проблем при абстракцията на SQL идва от липсата на поддръжка в JPA на важни SQL функционалности, дори такива, които се смятат за основни. Пример са всички set операции (UNION, INTERSECT, EXCEPT). Ако имате нужда от по-комплексна SQL функционалност е много вероятно JPA да не я поддържа.

Използването на JPA става по-трудно пропорционално със сложността на заявките, които се опитваме да изпълним. За по-комплексни заявки, обикновено свързани с четене от базата, SQL често е по-добрия избор. Имайте го предвид следващия път, когато някой ви поиска да напишете по-завъртян репорт.

Абстракция на базата

Предимство на ORM е лесната замяна на базата с друга. На пръв поглед това не е нещо, което се налага често. Примерна практика е тестовете да използват бърза, in-memory база данни, докато production и подобните му среди да използват истинската такава. Абстракцията на базата прави това лесно.

Какво губим? Много от базите имат по-специфични функции, които могат да бъдат важни за нас. Естествено няма как JPA едновременно да прави нашия код независим от типа база и да ги поддържа. Често и самата стандартна практика на използване на различни типове база за разработка и production се обръща срещу нас, криейки важни разлики.

Performance

Много ORM използват кеширане за подобрен performance. Хубавото в случая е, че не се налага вие, като програмист, да правите кой знае какво за да го използвате. В този блог пост няма да навлизам в подробности за различните видове кеш. Все пак не мисля, че performance-a при използването на ORM и просто като пишем SQL се различава съществено стига програмиста разбира какво прави и не използва SQL или JPA/Hibernate когато другия подход е за предпочитане.

Какви проблеми обаче бихме могли да имаме? Примерно ORM не са толкова подходящи за операции, когато ни се налага масово четене и писане. В такива случаи по-директен контрол над SQL-a е наложителен. Не използвайте N заявки, когато можете да минете само с една, защото това може да се случи и с вашата база:

Картинката реално показва какво се случи когато заменихме 1000 заявки с една – и като продължителност, и като натоварване.

JDBC – предимства и недостатъци

Добър избор ако се налага повече комплексни заявки, масово писане/четене, по-специфични database features и други.

Директно използване на SQL

Ако искаме пълен контрол над нашия SQL, JDBC ни предоставя тази възможност. Можем да изпълним и напишем каквото си поискаме, стига да е валиден SQL.

Използвайки го не се ограничаваме от нищо и можем да пишем и използваме функционалност в SQL, недостъпна за нас или трудна за използване ако минаваме през абстракция като JPA.

Това има и своята цена – SQL в Java представлява на практика просто текст. Какво ни пречи това?

  • Налага се да научим SQL 🙂
  • Откриване на грешки чак при изпълнение – води до по-бавна разработка
  • Липса на понятия като методи / променливи, които правят кода ни по-лесен за разбиране и преизползване

Проблемите са сериозни, тъй като често ни се налага да използваме SQL директно именно когато ни се налага да пишем сложни и дълги заявки.

Flexibility

JDBC ни дава пълен контрол над всички конфигурации свързани с връзката с базата ни данни. Това ни дава мощ да правим каквото си искаме, с цената на писане на повече код.

Колко повече код?

Ами можем (и понякога ни се налага), да се “занимаваме” с:

  • Data Source
  • Connection
  • PreparedStatement + PreparedStatement parameters
  • ResultSet – един или повече редове?
  • Превръщане обратно в обекти
  • И да не забравим да „почистим“ и затворим каквото сме „отворили“

Голяма част от горното е решено от фреймуърците, които използваме и не се налага наистина да го правим всеки път. Добър пример е Spring JDBCTemplate.

Все пак JDBC е мощен инструмент, но на ниско ниво и съответно с малко „шумно“ API, изискващо повечко церемонии.

Заключение

Кое да изберем и нужно ли е да избираме изобщо?

Кое идва първо? Базата или модела във вашия код?

В случай, че не ви интересува особено къде точно искате да запазите своите данни, използването на ORM често е за предпочитане. Моделът, както е дефиниран във вашия Java (или друг език) код е това, което е на първо място.

Обратния случай е ако базата ви стои на първо място и чак след това мислите за това какъв модел да използвате в своя Java код. Част от логиката ви може да бъде в stored procedures, както и да използвате triggers или друга функционалност на базата. В този случай ORM в много случаи ще пречи и е важно да пишете сами своя SQL.

Как използвате базата?

И по-точно колко са сложни операциите, които правите и колко по-важно е писането от четенето?

Повечето приложения прекарват доста повече време четейки от базата, вместо пишейки, но това само по-себе си не е достатъчно, за да вземем решение кой подход да използваме.

Ако четенето и писането са сравнително прости – спестете си време и код и използвайте ORM.

Четенето ви е сложно, с много свързани обекти и комплексни заявки? Пишете си сами SQL-a. В такива случаи ORM често повече пречи, отколкото помага.

Писането в базата ви е доста сложно, с множество взаимно-свързани обекти, които трябва да се обработят правилно и наведнъж? Използвайте ORM. Между другото Hibernate е създаден именно за да реши този проблем!

Не използвайте едно решение за всичко!

Ами ако имате нужда едновременно комплексно да четете и пишете?

Не избирайте, използвайте и двете.

Естествено решението никога не е просто и зависи и от други фактори. Екип, който има задълбочени познания в SQL ще избира различно от друг, пълен с Hibernate експерти.

Какво е вашето мнение? Виждате неточност? Моля, споделете в коментарите 🙂


Автор:

Костадин Голев

>>> Костадин Голев е Team Lead в Ocado Technology.
>>> Той е Java програмист и team lead с повече от 10 години опит.
>>> Има силен интерес към test automation.
>>> Coderetreat & coding dojo организатор.
>>> Обича да пише в kgolev.com.

 

 

 


Стани част от Java потребителската група на DEV.BG.

Абонирай се и ще ти изпращаме информация за всичко, което предстои в групата.

You have Successfully Subscribed!

Прочети още:
JavaScript: Ненужните части
Разговор за JavaScript с Мартин Чаов

Share This