W trakcie tworzenia rozbudowanych aplikacji, praca z bazą danych jest niemal nieunikniona. Aplikacje te zazwyczaj wymagają implementacji operacji CRUD, czyli możliwości tworzenia, pobierania, modyfikowania i usuwania danych.
Do tego celu niezbędna jest baza danych. Jeśli tworzysz aplikację w obiektowym języku programowania, takim jak JavaScript, i korzystasz z relacyjnej bazy danych, np. MySQL, obsługa danych może okazać się skomplikowana.
Jako programista JavaScript, musisz zagłębić się w szczegóły funkcjonowania relacyjnych baz danych oraz opanować składnię SQL, by móc pisać złożone zapytania niezbędne dla twojej aplikacji.
Warto pamiętać, że relacyjne bazy danych przechowują dane w tabelach z wierszami i kolumnami, podczas gdy JavaScript bazuje na obiektach i relacjach między nimi. Taki rozdźwięk może być bardzo czasochłonny i trudny do rozwiązania. Dlatego właśnie tak przydatne okazuje się narzędzie zwane Object Relational Mapper (ORM).
Mapowanie Obiektowo-Relacyjne (ORM)
ORM to technologia, która pozwala programistom pracować z relacyjnymi bazami danych, stosując paradygmaty programowania obiektowego.
ORM pełni rolę pośrednika między kodem aplikacji a wybraną relacyjną bazą danych. Umożliwia programistom interakcję z bazą danych za pomocą tych samych koncepcji obiektowych, które wykorzystują w swoim kodzie aplikacji.
ORM mapuje tabele z relacyjnej bazy danych na klasy, których instancje reprezentują poszczególne rekordy, czyli wiersze tabeli. Atrybuty klas odpowiadają kolumnom w tych tabelach.
W praktyce oznacza to, że programiści mogą używać swojego ulubionego języka programowania do tworzenia, pobierania, aktualizowania, usuwania i zarządzania danymi zapisanymi w bazie, bez konieczności pisania skomplikowanych poleceń SQL.
Dzięki ORM ograniczasz ilość kodu SQL, który musisz czytać, a także unikasz konieczności nauki nowego języka zapytań, aby pracować z bazą danych.
Aby lepiej zrozumieć działanie ORM, spójrz na poniższe zapytanie MySQL, które ma na celu wyszukanie użytkowników z działu IT:
SELECT * FROM users WHERE department="IT";
Identyczne zapytanie, przy użyciu ORM dla JavaScript, może wyglądać tak, jak pokazano poniżej. Widać wyraźnie, że do jego utworzenia użyto standardowego JavaScript:
const users = await User.findAll({ where: { department: 'IT', }, });
Korzyści z Zastosowania ORM
Używanie ORM przynosi wiele korzyści programistom JavaScript. Do najważniejszych z nich należą:
Abstrakcja Złożoności Baz Danych
ORM ukrywa złożoność baz danych, umożliwiając programistom komunikację z bazą danych za pośrednictwem języka programowania, a nie za pomocą skomplikowanego SQL.
Niektóre ORM oferują także konstruktory zapytań, dzięki którym pisanie zaawansowanych zapytań staje się proste, bazując na zasadach programowania obiektowego. Dzięki temu, programiści mogą tworzyć kod bardziej przejrzysty i łatwiejszy w utrzymaniu, debugowaniu i modyfikacji.
Wzrost Produktywności
ORM eliminuje potrzebę pisania zapytań SQL, zarządzania połączeniami z bazą danych i pozwala programistom skupić się na logice biznesowej aplikacji, która jest jej kluczowym elementem.
Dodatkowo, programiści pracują z bazami danych w dobrze znanym im paradygmacie OOP, bez potrzeby pisania dużej ilości kodu pomocniczego czy wykonywania powtarzalnych zadań.
ORM można wykorzystać również do automatycznego wypełniania baz danych oraz generowania kodu dostępu do danych. Te czynniki znacząco wpływają na zwiększenie produktywności.
Niezależność od Bazy Danych
Istotną zaletą ORM jest możliwość pisania kodu aplikacji niezależnie od używanej bazy danych. Dzięki temu kod nie jest powiązany z jedną konkretną bazą danych, co pozwala na łatwą zmianę bazy danych, z której korzysta aplikacja, bez konieczności modyfikacji dużej części kodu.
Jest to niezwykle ważne, szczególnie gdy aplikacja ewoluuje lub musi wspierać wiele baz danych jednocześnie.
Proste Zarządzanie Schematami i Relacjami
ORM upraszcza pracę ze schematami bazy danych oraz zarządzanie relacjami pomiędzy różnymi jej elementami.
Niektóre ORM oferują funkcje automatycznego generowania schematów z istniejących baz danych. Większość z nich udostępnia metody, które umożliwiają łatwe definiowanie relacji pomiędzy tabelami i zarządzanie nimi.
Większe Bezpieczeństwo
ORM zapewnia zwiększone bezpieczeństwo, ponieważ filtruje dane oraz wewnętrznie korzysta z zapytań parametryzowanych. Zapytania parametryzowane wykorzystują symbole zastępcze dla wartości wejściowych, zamiast bezpośrednio umieszczać dane dostarczone przez użytkownika.
Dzięki temu dane wprowadzone przez użytkownika nigdy nie są bezpośrednio wstawiane do zapytania SQL. W ten sposób ORM chroni aplikację przed atakami typu SQL injection, zwiększając jej poziom bezpieczeństwa.
Wady Korzystania z ORM
Mimo wielu zalet, korzystanie z ORM ma również pewne wady. Przede wszystkim, wprowadzenie dodatkowej warstwy abstrakcji między aplikacją a bazą danych może powodować obniżenie wydajności i większe zużycie pamięci.
Ponadto, aby skutecznie korzystać z ORM, programiści muszą nauczyć się jego obsługi. Nie można też pominąć podstawowej wiedzy na temat SQL, aby rozumieć, co tak naprawdę dzieje się pod maską.
Mimo tych wad, ORM pozostają bardzo przydatnym narzędziem dla programistów. Stanowią najłatwiejszy i najlepszy sposób na interakcję z relacyjnymi bazami danych z aplikacji opartych na paradygmacie OOP. Aby pomóc Ci rozpocząć przygodę z ORM, przedstawiamy kilka z najlepszych, które możesz wykorzystać w swoich aplikacjach JavaScript.
Sequelize
Jak podaje oficjalna dokumentacja, Sequelize to nowoczesny ORM dla TypeScript i Node.js, który wspiera bazy danych Oracle DB, PostgreSQL, MySQL, MariaDB, SQLite, Microsoft SQL Server, IBM DB2 i Snowflake. Ten open-source’owy ORM jest bardzo popularny wśród programistów korzystających z frameworka Node.js w połączeniu z relacyjnymi bazami danych.
Popularność ta wynika z jego rozbudowanego zestawu funkcji, które ułatwiają pracę z relacyjnymi bazami danych w Node.js. Przede wszystkim, Sequelize jest ORM opartym na obietnicach, co pozwala mu na bezproblemową obsługę asynchronicznych operacji, które są fundamentalne dla Node.js.
Sequelize obsługuje także szybkie ładowanie, w którym zasoby są pobierane natychmiast po wykonaniu kodu aplikacji oraz ładowanie leniwe, gdzie zasoby są ładowane dopiero gdy są faktycznie potrzebne. Sequelize ma również solidne wsparcie transakcji, replikacji odczytu i walidacji modeli, a także umożliwia migracje i synchronizację baz danych.
Użytkownicy mogą również definiować zależności i relacje między modelami podczas korzystania z Sequelize. Podsumowując, oferuje on bogaty zestaw opcji zapytań, umożliwiając programistom łatwe tworzenie zaawansowanych zapytań do baz danych.
Prisma
Prisma to open-source’owy ORM, który ułatwia zarządzanie bazą danych i interakcję z nią z dowolnego środowiska JavaScript lub TypeScript.
Prisma obsługuje PostgreSQL, MySQL, Microsoft SQL Server, CockroachDB, SQLite i MongoDB. Dodatkowo, umożliwia łatwą integrację z dowolnym frameworkiem JavaScript lub TypeScript, upraszczając pracę z bazami danych i zwiększając bezpieczeństwo typów.
Aby wspomóc programistów w tworzeniu zapytań, Prisma oferuje funkcję Prisma Client, która zawiera mechanizm autouzupełniania i pozwala programistom tworzyć bezpieczne typowo zapytania, dostosowane do schematu wykorzystywanego w ich aplikacji.
Programiści mogą tworzyć własne schematy od podstaw lub wykorzystać Prisma do automatycznego generowania schematów poprzez introspekcję istniejącej bazy danych.
Kolejną funkcją Prisma jest Prisma Migrate, narzędzie do migracji schematów, które automatycznie generuje konfigurowalne migracje SQL, zapewniając użytkownikom pełną kontrolę i elastyczność podczas wdrażania aplikacji ze środowiska deweloperskiego do produkcyjnego.
Na koniec, użytkownicy Prisma mają dostęp do Prisma Studio, interfejsu administratora, który umożliwia przeglądanie, analizowanie, modyfikowanie i zrozumienie danych przechowywanych w bazie danych. Wszystkie te cechy czynią Prismę znakomitym ORM-em dla programistów JavaScript i TypeScript.
TypeORM
TypeORM to open-source’owy ORM, który został stworzony, by nieustannie wspierać najnowsze funkcje JavaScript i dostarczać dodatkowe możliwości, dzięki którym programiści mogą tworzyć dowolny rodzaj aplikacji korzystających z baz danych.
TypeORM obsługuje bazy danych MySQL, MariaDB, PostgreSQL, CockroachDB, SQLite, Microsoft SQL Server, Oracle, SAP Hana i sql.js.
TypeORM wspiera zarówno JavaScript, jak i TypeScript i obsługuje MongoDB, która nie jest relacyjną bazą danych. TypeORM działa w Node.js, przeglądarce, platformach Ionic, Cordova, React Native, NativeScript, Expo i Election.
TypeORM umożliwia programistom pracę z wieloma typami baz danych i korzystanie z wielu instancji baz danych jednocześnie. Obsługuje również buforowanie i zapytania, logowanie, transakcje, asocjacje, relacje chętne i leniwe, oraz pozwala na migracje i automatyczne generowanie migracji.
TypeORM obsługuje również DataMapper, ActiveRecord, przesyłanie strumieniowe nieprzetworzonych wyników, zapytania między bazami danych i schematami, a także oferuje użytkownikom potężne narzędzie do tworzenia zapytań.
MikroORM
MikroORM to open-source’owy ORM dla TypeScript, który wspiera MySQL, MariaDB, PostgreSQL, SQLite i MongoDB. Ten ORM bazuje na Datamapper, Identity Map Pattern i Unit of Work. Jednostka pracy służy do utrzymywania listy obiektów, których dotyczy transakcja, oraz koordynuje wprowadzanie zmian.
Umożliwia to automatyczną obsługę transakcji, grupowanie wszystkich zapytań oraz implementację logiki biznesowej bezpośrednio w wykorzystywanych jednostkach.
MikroORM zawiera również QueryBuilder obsługujący metadane z automatycznym łączeniem oraz system zdarzeń, który można wykorzystać do integracji z cyklem życia encji i zmiany sposobu działania UnitOfWork.
Ułatwione jest również wypełnianie bazy danych początkowymi danymi dzięki siewnikowi, który pozwala generować dane testowe o dowolnej objętości i wykorzystać je do zasiewania bazy danych.
Ostatnią wartą wzmianki funkcją MikroORM jest łatwa obsługa migracji bazy danych.
Bookshelf.js
Bookshelf to open-source’owy ORM dla JavaScript i Node.js. Jego celem jest dostarczenie prostej biblioteki do wykonywania typowych zadań podczas wysyłania zapytań do baz danych w JavaScript i tworzenia relacji między obiektami. Bookshelf jest przeznaczony do współpracy z PostgreSQL, MySQL i SQLite3.
Jako ORM dla Node.js, Bookshelf wspiera obietnice i tradycyjne wywołania zwrotne podczas pracy z ORM z poziomu aplikacji Node.js. Dodatkowo, obsługuje transakcje, asocjacje polimorficzne, ładowanie relacji (chętne/zagnieżdżone) i różnorodne typy relacji.
Bookshelf nie oferuje takiego samego poziomu funkcjonalności jak bardziej rozbudowane ORM, ale wyróżnia się prostotą, elastycznością i łatwością czytania oraz rozszerzania kodu. Jeśli potrzebujesz prostego i wydajnego ORM dla swojego projektu JavaScript, Bookshelf jest doskonałym wyborem.
Node ORM2
Node ORM2 to prosty i lekki ORM dla Node.js, który obsługuje bazy danych MySQL, SQLite i Progress OpenEdge. Ten ORM ułatwia pracę z modelami w Node.js. Podczas pracy z modelami oferuje funkcje tworzenia, synchronizacji, usuwania, pobierania, wyszukiwania, usuwania, zliczania i tworzenia masowego.
Umożliwia tworzenie relacji między modelami oraz definiowanie własnych walidacji, poza tymi wbudowanymi. Node ORM2 implementuje zasadę pojedynczej instancji, dzięki której wielokrotne pobieranie tego samego wiersza zwraca zawsze ten sam obiekt.
Waterline
Waterline to oparty na adapterach ORM dla Node.js. Jest to domyślny ORM dostarczany wraz z frameworkiem Sails. Jednak Waterline może być używany również bez Sails.
Jako ORM oparty na adapterach, Waterline umożliwia pracę z różnymi systemami baz danych za pomocą adapterów. Oficjalnie wspierane bazy danych to MySQL, PostgreSQL, MongoDB, Redis i lokalna pamięć masowa.
Istnieją też adaptery społecznościowe dla CouchDB, SQLite, Oracle, Microsoft SQL Server, DB2, Riak, neo4j, OrientDB, Amazon RDS, DynamoDB, Azure Table, RethinkDB i Solr.
Waterline pozwala korzystać z wielu baz danych w projekcie i zapewnia jednolite API do pracy z różnymi bazami i protokołami. Dzięki temu kod napisany z użyciem Waterline może współpracować z dowolną bazą danych wspieraną przez ORM bez potrzeby modyfikacji kodu.
Waterline został zaprojektowany z naciskiem na modułowość, testowalność i spójność między adapterami, dzięki czemu jest łatwy w użyciu i integracji z różnymi bazami danych.
Objection.js
Objection.js to ORM, którego celem jest ułatwienie wykorzystania pełnej mocy SQL i bazowego silnika bazy danych.
Oferuje zalety konstruktora zapytań SQL, wspierając pracę z relacjami. Konstruktor zapytań SQL to narzędzie, które ułatwia tworzenie złożonych zapytań.
Objection.js udostępnia prosty sposób na definiowanie modeli i relacji między nimi. Oferuje pełne możliwości CRUD, wykorzystując przy tym pełną moc SQL, a także ułatwia tworzenie transakcji.
Użytkownicy mogą także korzystać z funkcji „eager loading”, wstawiania i aktualizacji grafów obiektów, przechowywać złożone dokumenty w pojedynczych wierszach i walidować schematy JSON. Objection.js ma oficjalne wsparcie dla TypeScript i JavaScript.
Podsumowanie
Jako programista pracujący z relacyjnymi bazami danych w aplikacjach JavaScript lub TypeScript, znacznie lepiej jest korzystać z ORM.
Nie tylko upraszcza to interakcję z bazą danych, ale również zwiększa produktywność, zmniejsza ilość kodu SQL do napisania i podnosi poziom bezpieczeństwa aplikacji.
Wybierając ORM, zastanów się nad wykorzystaniem jednego z wymienionych w tym artykule, biorąc pod uwagę funkcje najlepiej dopasowane do twojej aplikacji.
Możesz również zapoznać się z listą najlepszych kompilatorów JavaScript online.
newsblog.pl
Maciej – redaktor, pasjonat technologii i samozwańczy pogromca błędów w systemie Windows. Zna Linuxa lepiej niż własną lodówkę, a kawa to jego główne źródło zasilania. Pisze, testuje, naprawia – i czasem nawet wyłącza i włącza ponownie. W wolnych chwilach udaje, że odpoczywa, ale i tak kończy z laptopem na kolanach.