Jaki preferujesz ORM Java i dlaczego? [Zamknięte]


262

To dość otwarte pytanie. Rozpocznę nowy projekt i przyjrzę się różnym ORM do zintegrowania z dostępem do bazy danych.

Czy masz jakieś ulubione? Czy są jakieś zalecenia dotyczące trzymania się z daleka?



Spójrz na mikro ORMs - Cienkie obwolut wokół technologii dostępu DB platformy - jak sql2o dla Java github.com/aaberg/sql2o lub ServiceStack.OrmLite NET github.com/ServiceStack/ServiceStack.OrmLite
tomaszkubacki

3
Po ponad 5 latach używania ORM mój osobisty wybór to Spring JDBC zamiast ORM, a drugim najlepszym jest iBatis (MyBatis), nie lubię hibernacji z powodu krzywej uczenia się, mniejszej kontroli i problemów z wydajnością.

Oto (również zamknięta) lista lekkich opakowań jdbc, które mogą być używane jako alternatywa dla pełnych wersji orms: stackoverflow.com/questions/7137929/...
Vadzim

Odpowiedzi:


237

Przestałem używać ORM.

Powodem tego nie jest żadna wielka wada koncepcji. Hibernacja działa dobrze. Zamiast tego odkryłem, że zapytania mają niewielki narzut i mogę dopasować wiele skomplikowanej logiki do dużych zapytań SQL i przenieść dużą część mojego przetwarzania do bazy danych.

Rozważ więc użycie pakietu JDBC.


81
Z ORM to wciąż ta sama historia: przyjemny szybki wstępny rozwój i duże obciążenie zasobów w dalszej części projektu podczas śledzenia błędów i nieefektywności związanych z ORM. Nienawidzę również faktu, że wydaje się, że daje to pomysł programistom, aby nigdy nie musieli pisać konkretnych zoptymalizowanych zapytań.
Eelco

7
Hej, czy to wszystko dotyczy dużych, prawdziwych projektów?
santiagobasulto

30
Zgadzam się. Używam ORM już od 3 lat i nie mogę powiedzieć, ile czasu zostało (wciąż jest) stracone na rozwiązanie problemów związanych z uporczywością. Nie mamy żadnej kontroli nad tym, co dzieje się „pod maską”, konfiguracji jest zbyt wiele, aby można było nimi skutecznie zarządzać, a są zachowania, które mogą doprowadzić do szaleństwa. Z drugiej strony mam wsparcie dla głównych baz danych i nigdy nie muszę się martwić o ich różnice.
marcolopes,

58
dlaczego nie skorzystać z obu, w zależności od złożoności zapytania / transakcji? to nie jest tak, że się wykluczają.
amfibia

6
@WillSheppard yes Will. Używam Django ORM dość często i działa świetnie. Myślę, że różnica może wynikać z dynamicznej natury Pythona (i Perla). Korzystanie z ORM w Javie jest uciążliwe. Ale w dynamicznych językach może być naprawdę wyrazisty. Istnieje kilka świetnych projektów do osadzania operacji ORM, takich jak DSL w Pythonie, i są świetne.
Santiagobasulto

97

Brak, ponieważ posiadanie ORM zabiera zbyt dużą kontrolę przy niewielkich korzyściach. Oszczędności czasu można łatwo zignorować, gdy trzeba debugować nieprawidłowości wynikające z użycia ORM. Ponadto ORM zniechęcają programistów do uczenia się SQL i tego, jak działają relacyjne bazy danych, i korzystania z nich na ich korzyść.


4
Zgadzam się z tym stwierdzeniem. Ile z całkowitego czasu programowania zajmie napisanie kodu trwałości? Myślę, że mniej niż 10-15%
adrian.tarau

16
To zależy. Oczywiście, jeśli używasz tylko jednego określonego rodzaju bazy danych, łatwo jest uciec od korzystania z ORM. Jednak gdy potrzebujesz obsługi innych rodzajów baz danych, może to szybko stać się trudniejsze do zarządzania.
Jason Baker

3
„Oszczędności czasu można łatwo zmarnować, gdy trzeba debugować nieprawidłowości wynikające z użycia ORM” Nie jest to prawdą, gdy krzywa umiejętności jest dobrym czynnikiem przy wyborze technologii.
elsadek

7
Twój argument może być przedstawiony przeciwko wykorzystaniu dowolnej biblioteki. Największe korzyści z ORM to takie rzeczy, jak jednostki pracy, mapowanie obiektów, śledzenie zmian, leniwe ładowanie, migracje i relacje. Cudownie jest móc napisać user.profile.givenName i nie dbać o to, jaką strukturę wykorzystano do przechowywania danych.
Alex

1
Można go używać przeciwko dowolnej bibliotece, ale w różnym stopniu. Generalnie jestem wielkim zwolennikiem korzystania z bibliotek - po co wymyślać koło ponownie? Jednak w tym przypadku wydaje mi się, że Hibernacja jest do większości zastosowań zbyt ciężka, a bardziej lekki ORM byłby bardziej preferowany. Moje doświadczenia opierają się na kilkunastoletnim doświadczeniu rozwijającym się w Hibernacji i dokładnym poznawaniu jego tajników.
simon

92

Wiele ORM jest świetnych, musisz wiedzieć, dlaczego chcesz dodać abstrakcję na JDBC. Mogę ci polecić http://www.jooq.org (zastrzeżenie: jestem twórcą jOOQ, więc ta odpowiedź jest stronnicza). jOOQ obejmuje następujący paradygmat:

  • SQL jest dobrą rzeczą. Wiele rzeczy można ładnie wyrazić w SQL. Nie ma potrzeby pełnej abstrakcji SQL.
  • Relacyjny model danych jest dobrą rzeczą. Sprawdził się jako najlepszy model danych od ostatnich 40 lat. Nie ma potrzeby korzystania z baz danych XML ani zorientowanych obiektowo modeli danych. Zamiast tego Twoja firma obsługuje kilka instancji Oracle, MySQL, MSSQL, DB2 lub dowolnego innego RDBMS.
  • SQL ma strukturę i składnię. Nie powinno się tego wyrażać przy użyciu „niskiego poziomu” konkatenacji ciągów w JDBC - ani „wysokiego poziomu” konkatenacji ciągów w HQL - oba są podatne na błędy składniowe.
  • Wiązanie zmienne jest zwykle bardzo złożone w przypadku dużych zapytań. TO jest coś, co powinno być abstrakcyjne.
  • POJO są świetne podczas pisania kodu Java manipulującego danymi w bazie danych.
  • POJO to kłopot z pisaniem i utrzymywaniem ręcznie. Generowanie kodu jest właściwą drogą. Otrzymasz zapytania zgodne z kompilacją, w tym bezpieczeństwo typu danych.
  • Baza danych jest na pierwszym miejscu. Chociaż aplikacja nad bazą danych może się zmieniać z czasem, sama baza danych prawdopodobnie będzie trwać dłużej.
  • Tak, masz procedury składowane i typy zdefiniowane przez użytkownika (UDT) w starej bazie danych. Twoje narzędzie bazy danych powinno to obsługiwać.

Istnieje wiele innych dobrych ORM. Zwłaszcza Hibernacja lub iBATIS mają świetną społeczność. Ale jeśli szukasz intuicyjnego, prostego, powiem, wypróbuj jOOQ. Pokochasz to! :-)

Sprawdź ten przykładowy SQL:

  // Select authors with books that are sold out
  SELECT * 
    FROM T_AUTHOR a
   WHERE EXISTS (SELECT 1
                   FROM T_BOOK
                  WHERE T_BOOK.STATUS = 'SOLD OUT'
                    AND T_BOOK.AUTHOR_ID = a.ID);

I jak można to wyrazić w jOOQ:

  // Alias the author table
  TAuthor a = T_AUTHOR.as("a");

  // Use the aliased table in the select statement
  create.selectFrom(a)
        .whereExists(create.selectOne()
                           .from(T_BOOK)
                           .where(T_BOOK.STATUS.equal(TBookStatus.SOLD_OUT)
                           .and(T_BOOK.AUTHOR_ID.equal(a.ID))))));

1
Narzędzia ORM są tak świetne, jak potrafisz z nich prawidłowo korzystać. Są projekty, w których narzędzia ORM działają jak amulety, podczas gdy w innych nie pasują wcale. Ostatecznie do obowiązków zespołu programistów należy wybranie odpowiedniego narzędzia do wymagań projektu. Narzędzia ORM są złożone. Niestety tylko część wszystkich programistów poświęci czas na zrozumienie, jak działają. Reszta po prostu obwinie narzędzie i powie, że jest złe. Pytanie brzmi: czy najbardziej pozytywna odpowiedź oferuje najlepszą poradę? > Rozważ więc użycie pakietu JDBC. Czy naprawdę chcemy używać zwykłego JDBC?
Vlad Mihalcea

Staram się nie dopuścić do tego, aby baza danych była pierwsza. Aplikacja zawiera reguły biznesowe dotyczące funkcji, o które prosi klient, i prawie nigdy nie prosi o utworzenie bazy danych. To szczegół techniczny ustalany podczas wdrażania.
Kwebble,

58

Hibernacja, ponieważ jest to po prostu standard defacto w Javie i był jedną z sił napędowych w tworzeniu JPA. Ma doskonałą obsługę na wiosnę i obsługuje ją prawie każda platforma Java. Wreszcie, GORM jest naprawdę fajnym narzędziem do tworzenia dynamicznych wyszukiwarek itd. Przy użyciu Groovy.

Został nawet przeniesiony do .NET (NHibernate), więc możesz go również tam używać.


4
Głosuję również na Hib, ale z ważnym dodatkiem: powinniśmy używać JPA API tylko wtedy, gdy implementacja JPA jest faktycznie zapewniana przez Hib.
Vladimir Dyuzhev

52

Hibernacja, ponieważ:

  • jest stabilny - będąc na tyle wiele lat, nie ma w nim większych problemów
  • dyktuje standardy w dziedzinie ORM
  • implementuje standard (JPA), oprócz dyktowania go.
  • ma mnóstwo informacji na ten temat w Internecie. Istnieje wiele samouczków, typowe rozwiązania problemów itp
  • jest potężny - możesz przełożyć bardzo złożony model obiektowy na model relacyjny.
  • ma wsparcie dla każdego dużego i średniego RDBMS
  • jest łatwy w obsłudze, gdy dobrze się nauczysz

Kilka punktów, dlaczego (i kiedy) używać ORM:

  • pracujesz z obiektami w twoim systemie (jeśli twój system został dobrze zaprojektowany). Nawet jeśli użyjesz JDBC, skończysz tworzyć warstwę tłumaczenia, aby przenieść dane do obiektów. Ale zakładam się, że hibernacja jest lepsza w tłumaczeniu niż jakiekolwiek niestandardowe rozwiązanie.
  • nie pozbawia cię kontroli. Możesz kontrolować rzeczy w bardzo małych szczegółach, a jeśli interfejs API nie ma funkcji zdalnej - wykonaj natywne zapytanie i masz je.
  • żaden średni lub większy system nie może sobie pozwolić na tonę zapytań (czy to w jednym miejscu, czy też rozproszonych), jeśli ma na celu utrzymanie
  • jeśli wydajność nie jest krytyczna. Hibernacja dodaje narzut wydajności, którego w niektórych przypadkach nie można zignorować.

Kiedy porównuję Hibernata i JPA, wybieram Hibernację, a jeśli porównuję JPA i JDO, wybieram JDO! Bardzo lubię JDO, ale uwielbiam dwie funkcje Hibernacji (które nie są dostępne w JDO), jedna to @Filtry, a druga to możliwość mapowania pól wersji (dla optymistycznego blokowania) na normalne pola, co nie jest możliwe w JDO .
Amir Pashazadeh

27

Polecam korzystanie z MyBatis . Jest to cienka warstwa na JDBC, bardzo łatwo jest mapować obiekty na tabele i nadal używać zwykłego SQL, wszystko jest pod twoją kontrolą.


10
Ibatis dla skomplikowanych odczytów i hibernacja do tworzenia, aktualizacji usuwania i prostych odczytów to idealny wybór.
darpet

19

Miałem naprawdę dobre doświadczenia z Avaje Ebean, kiedy pisałem średniej wielkości aplikację JavaSE.

Używa standardowych adnotacji JPA do definiowania jednostek, ale udostępnia znacznie prostszy interfejs API (brak bzdury EntityManager lub dowolnego z tych dołączonych / odłączonych elementów) Pozwala także w razie potrzeby łatwo używać zapytań SQL lub zwykłych wywołań JDBC zdarzeń.

Ma również bardzo ładny płynny i bezpieczny dla API interfejs do zapytań. Możesz pisać takie rzeczy jak:

List<Person> boys = Ebean.find(Person.class)
                                  .where()
                                       .eq("gender", "M")
                                       .le("age", 18)
                                  .orderBy("firstName")
                                  .findList();

6
Muszę być trochę dziwny ... wybierz z Osoby, w której płeć = „M” i wiek <18 posortowane według firstName wygląda dla mnie o wiele lepiej :-)
Eelco

4
To jeden z lepszych ormów, jakie widziałem w Javie. Decyzja o zastosowaniu singletonu jest odświeżająca i daje mu ogromną praktyczną przewagę nad innymi.
opsb

Myślę, że masz na myśli płynność, a nie płyn.
Montdidier,

@opsb Myślę, że technicznie jest to monostat, a nie singleton.
Montdidier,

Jak zacząć korzystać z Avaje Ebean ORM? Wszelkie filmy instruktażowe?
Avinash,

11

SimpleORM , ponieważ jest prosty i nie ma magii. Definiuje wszystkie struktury metadanych w kodzie Java i jest bardzo elastyczny.

SimpleORM zapewnia funkcjonalność podobną do Hibernacji poprzez mapowanie danych w relacyjnej bazie danych na obiekty Java w pamięci. Zapytania można określać w odniesieniu do obiektów Java, tożsamość obiektu jest dopasowywana do kluczy bazy danych, utrzymywane są relacje między obiektami, a zmodyfikowane obiekty są automatycznie opróżniane do bazy danych z optymistycznymi blokadami.

Ale w przeciwieństwie do Hibernacji, SimpleORM wykorzystuje bardzo prostą strukturę i architekturę obiektów, która eliminuje potrzebę złożonego analizowania, przetwarzania kodu bajtowego itp. SimpleORM jest mały i przezroczysty, pakowany w dwa słoiki o wielkości zaledwie 79K i 52K, z tylko jednym małym i opcjonalnym zależność (Slf4j). (Hibernacja ma ponad 2400 KB plus około 2000 KB zależnych słoików). To sprawia, że ​​SimpleORM jest łatwy do zrozumienia, a zatem znacznie zmniejsza ryzyko techniczne.


Nie korzystałem z niego, ale ActiveObjects opisuje się jako swego rodzaju Hibernacja-lite na swojej stronie internetowej, więc prawdopodobnie istnieje pewne podobieństwo.
Abdullah Jibaly

10

Eclipse Link , z wielu powodów, ale przede wszystkim czuję, że ma mniej wzdęć niż inne główne rozwiązania strumieniowe (co najmniej mniej wzdęć na twarzy).

Aha i Eclipse Link został wybrany jako referencyjna implementacja JPA 2.0


5

Chociaż podzielam obawy dotyczące zastępowania Java w zapytaniach SQL w dowolnej formie, naprawdę myślę, że ludzie krytykujący ORM robią to z powodu ogólnie złego projektu aplikacji.

True OOD jest sterowany przez klasy i relacje, a ORM zapewnia spójne mapowanie różnych typów relacji i obiektów. Jeśli użyjesz narzędzia ORM i skończysz na kodowaniu wyrażeń zapytań w dowolnym języku zapytań obsługiwanym przez strukturę ORM (w tym między innymi drzewa wyrażeń Java, metody zapytań, OQL itp.), Zdecydowanie robisz coś złego, tzn. Model klasy najprawdopodobniej nie spełnia twoich wymagań tak, jak powinno. Czysty projekt aplikacji tak naprawdę nie wymaga zapytań na poziomie aplikacji. Refaktoryzowałem wiele projektów, od których ludzie zaczęli używać frameworku ORM w taki sam sposób, w jaki używali ich do osadzania stałych ciągów SQL w swoim kodzie, a na koniec wszyscy byli zaskoczeni, jak prosta i łatwa w utrzymaniu jest cała aplikacja po dopasowaniu ulepszyć swój model klasy za pomocą modelu użytkowania. To prawda, że ​​do takich rzeczy jak funkcja wyszukiwania itp. Potrzebujesz języka zapytań, ale nawet wtedy zapytania są tak bardzo ograniczone, że tworzenie nawet złożonego WIDOKU i odwzorowanie go na trwałą klasę tylko do odczytu jest o wiele przyjemniejsze w utrzymaniu i analizie niż budowanie wyrażeń w języku zapytań w kodzie aplikacji. Podejście VIEW wykorzystuje również możliwości baz danych, a dzięki materializacji może być znacznie lepsze pod względem wydajności niż jakikolwiek odręczny SQL w źródle Java. Nie widzę więc żadnego powodu, by nietrywialna aplikacja NIE korzystała z ORM. ale nawet wtedy zapytania są tak bardzo ograniczone, że tworzenie nawet złożonego WIDOKU i mapowanie go na trwałą klasę tylko do odczytu jest o wiele łatwiejsze w utrzymaniu i oglądaniu niż budowanie wyrażeń w języku zapytań w kodzie aplikacji. Podejście VIEW wykorzystuje również możliwości baz danych, a dzięki materializacji może być znacznie lepsze pod względem wydajności niż jakikolwiek odręczny SQL w źródle Java. Nie widzę więc żadnego powodu, by nietrywialna aplikacja NIE korzystała z ORM. ale nawet wtedy zapytania są tak bardzo ograniczone, że tworzenie nawet złożonego WIDOKU i mapowanie go na trwałą klasę tylko do odczytu jest o wiele łatwiejsze w utrzymaniu i oglądaniu niż budowanie wyrażeń w języku zapytań w kodzie aplikacji. Podejście VIEW wykorzystuje również możliwości baz danych, a dzięki materializacji może być znacznie lepsze pod względem wydajności niż jakikolwiek odręczny SQL w źródle Java. Nie widzę więc żadnego powodu, by nietrywialna aplikacja NIE korzystała z ORM.


11
Jeśli budujesz aplikacje na bazie trwałego sklepu, jak wielu z nas, niezależnie od tego, czy jest to RDBMS, czy jakiś smak NoSQL, ten sklep będzie miał swój własny skuteczny sposób dostępu do niego. Zbyt wiele prób oderwania się od tego jest po prostu nadinżynierią. Nadmierna gorliwość w kwestii „prawdziwego OOD” sprawia, że ​​architektura astronautów, z których Java jest niesławna.
Eelco
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.