Co sądzisz o nowym narzędziu do utrzymywania Java, które tak naprawdę nie jest ORM? [Zamknięte]

12

Trwałość w Javie

Przez ostatnie lata zbierałem doświadczenie w dziedzinie abstrakcji trwałej w Javie, wykorzystując takie koncepcje, jak EJB 2.0, Hibernacja, JPA i domowe. Wydawało mi się, że mają stromą krzywą uczenia się i dużą złożoność. Ponadto, jako wielki fan SQL, myślałem również, że wiele modeli abstrakcji zapewnia zbyt dużo abstrakcji w stosunku do SQL, tworząc pojęcia takie jak „kryteria”, „predykaty”, „ograniczenia”, które są bardzo dobrymi koncepcjami, ale nie SQL.

Ogólna idea abstrakcji trwałości w Javie wydaje się być oparta na modelu relacyjno-obiektowym, w którym RDBMS jest w jakiś sposób dopasowany do świata OO. Debata ORM zawsze była emocjonalna, ponieważ wydaje się, że nie istnieje jedno rozwiązanie, które byłoby odpowiednie dla wszystkich - jeśli takie rozwiązanie mogłoby w ogóle istnieć.

JOOQ

Osobiście wolę, jak unikać problemów związanych z ORM, trzymać się świata relacyjnego. Teraz wybór paradygmatu modelu danych nie powinien być tematem dyskusji, ponieważ jest to osobista preferencja lub kwestia tego, który model danych najlepiej odpowiada konkretnemu problemowi. Dyskusja, którą chciałbym rozpocząć, dotyczy mojego własnego narzędzia trwałości o nazwie jOOQ . Zaprojektowałem jOOQ, aby zapewnić większość korzyści, jakie mają nowoczesne narzędzia do utrzymywania:

  • Język specyficzny dla domeny oparty na SQL
  • Generowanie kodu źródłowego odwzorowujące podstawowy schemat bazy danych na Javę
  • Obsługa wielu RDBMS

Dodanie niektórych funkcji, które ma niewiele nowoczesnych narzędzi do utrzymywania (popraw mnie, jeśli się mylę):

  • Obsługa złożonego SQL - związki, zagnieżdżone selekcje, autozłączenia, aliasing, zdania na zdania, wyrażenia arytmetyczne
  • Obsługa niestandardowych SQL - procedur przechowywanych, UDT, ENUMS, funkcji rodzimych, funkcji analitycznych

Więcej informacji można znaleźć na stronie dokumentacji: http://www.jooq.org/learn.php . Zobaczysz, że bardzo podobne podejście jest zaimplementowane w Linq dla C #, chociaż Linq nie jest przeznaczony wyłącznie dla SQL.

Pytanie

Teraz, kiedy powiedziałem, że jestem wielkim fanem SQL, zastanawiam się, czy inni programiści podzielą mój entuzjazm dla jOOQ (lub Linq). Czy takie podejście do abstrakcji trwałej jest realne? Jakie mogą być zalety / wady? Jak mogę ulepszyć jOOQ i czego według ciebie brakuje? Gdzie popełniłem błąd, koncepcyjnie lub praktycznie?

Doceniono krytyczne, ale konstruktywne odpowiedzi

Rozumiem, że debata jest emocjonalna. Istnieje wiele świetnych narzędzi, które już robią podobne rzeczy. To, co mnie interesuje, to krytyczna, ale konstruktywna informacja zwrotna, oparta na twoim doświadczeniu lub artykułach, które mogłeś przeczytać.

Lukas Eder
źródło
Czy obsługuje transakcje?
Armand
@Alison: Nie, chodzi tylko o SQL. Obsługa transakcji to bardzo złożony biznes, który moim zdaniem wiele innych narzędzi / platform (w tym EJB2 / 3) poradzi sobie lepiej niż jOOQ
Lukas Eder
Zdecydowanie poleciłbym bardzo solidny i szczegółowy przypadek użycia, w którym pokazujesz, że twoje podejście jest doskonałe do jego rozwiązania.
Należy również pamiętać, że edycja tego ciężkiego sprawi, że odpowiedzi będą mniej lub bardziej nieistotne, a zatem nie będą przydatne dla przyszłych czytelników. Zamiast tego zadaj nowe i lepsze pytanie.
Cześć Thorbjorn. Masz na myśli przypadek użycia inny niż pokazany na stronie przykładów? A może chciałbyś zobaczyć przykłady w samym pytaniu? O edycji: ogólnie masz rację. W tym przypadku jednak pomyślałem, że dwie dotychczasowe odpowiedzi byłyby trochę takie same ...
Lukas Eder,

Odpowiedzi:

5

Myślę, że jesteś na dobrej drodze i powinieneś kontynuować swoje rozwiązanie. Część poprzedniej krytyki jest zbyt surowa, ale poczyniono pewne ważne uwagi.

Ja również długo i intensywnie szukałem w pełni funkcjonalnego rozwiązania ORM, które pasowałoby do moich potrzeb, ale każde rozwiązanie, na które spojrzałem, okazało się krótkie. Każdy ma swoje zalety i wady, ale tak naprawdę nikt nie zrobił wszystkiego, co chciałem. Zgadzam się z twoją krytyką tych rozwiązań - a mianowicie, że są one na ogół złożone i mają dużą krzywą uczenia się.

Najlepszym konkurentem musiałby być de facto standard Hibernacja. Jest w pełni funkcjonalny, solidny i dobrze przetestowany. Szanuję to i doceniam za to, co to jest. Teraz, ryzykując obrażeniem połowy społeczności programistów, muszę również powiedzieć, że jest to rozdęty i złożony kawałek niedziałającego kodu. Spędziłem sporo czasu, grzebiąc w trzewiach, próbując debugować i zrozumieć, i nie byłem pod wrażeniem tego, co zobaczyłem. Powiedziawszy to, nadal polecam jako punkt wyjścia dla każdego, kto szuka dobrej ORM. Wyróżnia się prostym CRUD, ale nie używałbym go do wydajnych zapytań zbiorczych, takich jak eksploracja danych lub łamanie numerów.

Niestety, moja aplikacja jest bardziej zróżnicowana pod względem liczby (choć jest też trochę CRUD), więc postanowiłem stworzyć własną. Od samego początku wiedziałem, że będzie to mniej niż w porównaniu z innymi dostępnymi rozwiązaniami, ale będzie wystarczająco dobre i zapewni mi wydajność, której potrzebuję. Oto naprawdę świetna część: wygląda bardzo podobnie do twojego rozwiązania!

Myślę, że właśnie to zrobiłeś najlepiej: Podałeś swoje podstawowe przekonania jako rodzaj misji, a te przekonania są prawidłowe. Oczywiście poświęciłem sporo czasu na myślenie o tym problemie i jest to trudny do rozwiązania. Ale z biegiem czasu myślę, że społeczność programistów lepiej to rozumie, a my stworzymy lepsze rozwiązania. Uznanie dla wszystkich poprzednich wysiłków (szczególnie Hibernacji), ale myślę, że możemy to zrobić lepiej.

Twoje rozwiązanie lepiej rozwiązuje problem, ale rozwiązuje tylko jego część. Myślę, że podejście warstwowe może dać nam wszystko, czego chcemy. To, co wymyśliłeś / IMO, to warstwa fundamentowa. Jak zasugerowałeś, myślę, że ta warstwa najlepiej jest automatycznie generowana na podstawie schematu bazy danych. Powinien to być bardzo prosty relacyjny model obiektowy, który jest mapowany bezpośrednio na bazę danych i nie więcej. Masz rację, że dane utrzymują się znacznie dłużej niż kod, więc na tym poziomie dane powinny sterować kodem, a nie odwrotnie. Obsługuje CRUD, a także wydajne kwerendy zbiorcze. Prawdopodobnie zaimplementowałbym na tej warstwie pamięć podręczną L1.

Tym, co wyróżnia inne rozwiązania ORM, jest możliwość definiowania obiektów w sposób, który nie zależy tak bardzo od faktycznej struktury bazowej bazy danych. Dla tej funkcjonalności stworzyłbym kolejną warstwę. Z konieczności warstwa ta staje się bardziej abstrakcyjna, miejmy nadzieję, że jest prostsza (kosztem utraconej funkcjonalności) i opiera się na poprzedniej warstwie. Może wykorzystywać pamięć podręczną L2.

Jestem otwarty na posiadanie większej liczby warstw, ale dla mnie kluczową kwestią jest to, że poprzez zapewnienie wielu punktów wejścia do biblioteki możesz spełnić każdą potrzebę. Dla tych, którzy chcą prostego rozwiązania CRUD, które mapuje bezpośrednio na wybrane obiekty, mogą budować na górnej warstwie. Dla tych, którzy szukają czegoś potężniejszego i wydajniejszego, ale gotowi ponieść dodatkową złożoność, mogą podłączyć się do dolnej warstwy. Nie stworzyłbym specjalnego języka zapytań, ale zamiast tego ujawniłbym w tym celu obiekt konstruktora zapytań. A ponieważ kod jest warstwowy, ta funkcjonalność oczywiście istnieje bez specjalnego przekazywania.

Myślę, że rozumiesz przestrzeń i nie wymyślasz koła, ale raczej trafiłeś w nieco inną niszę. I szczerze mówiąc, jest to koło, które i tak mogłoby skorzystać z ulepszeń. Stajesz w obliczu ciężkiej bitwy przeciwko potęgom z przeszłości, ale jeśli twoje rozwiązanie jest dobre i myślę, że zmierza w tym kierunku, zyska popularność na własnych korzyściach.

Dale Anderson
źródło
Cześć Dale, dziękuję za zachętę! Podoba mi się twoje frazowanie o warstwach i jOOQ na najniższej warstwie z dalszą abstrakcją możliwą na jOOQ. To jest coś, z czym chcę się zmierzyć, gdy mam wystarczająco dużo rozpędu dzięki jOOQ. Interfejs z JPA i / lub Hibernacja będzie wyraźnie na mapie drogowej. Jak to ująłeś, narzędzia te wyróżniają się prostotą dzięki abstrakcji i mają wiele funkcji, których nie chcę w mojej warstwie: transakcje, sesje, pamięci podręczne L2 itp. PS: Czy twoje własne rozwiązanie jest własnością publiczną? Byłbym bardzo zainteresowany!
Lukas Eder
8

„Istnieje wiele magicznych kul i nie brakuje naiwnych programistów”.

Bez urazy, wygląda na to, że nie rozumiesz już, co zostało już zrobione w tej przestrzeni i dlatego wymyślasz nowe koła - doświadczenie powiedziałoby nam wszystko, że koła, które wymyśliłeś, chociaż schludne i zabawne, prawdopodobnie nie będą tak podobne dobre lub przydatne, ponieważ dostępne są już ładnie dopracowane koła.

quentin-starin
źródło
1
Dziękuję za opinię! Czy zagłębiłeś się w moją bibliotekę? Dokładnie staram się „porzucić O”, jak to nazywa twój artykuł. jOOQ chce, aby programiści pisali kod SQL, a nie mapowany według OR. Staram się osiągnąć to, co robi Linq dla platformy .NET, bez możliwości przepisania kompilatora Java. Gratulacje dla Microsoft za Linq! I odważę się powiedzieć, że nie jestem naiwny, ponieważ stworzyłem jOOQ po tym, jak nie byłem zadowolony z EJB 2.0 (jakiś czas temu) ani z Hibernacji. Właśnie z powodów, które wskazałeś w swoim artykule. Próbowałem tego, co zostało zrobione i nie odpowiadało moim potrzebom.
Lukas Eder,
jOOQ chce, aby programiści używali interfejsu API podobnego do kryteriów. To nie jest SQL. Jest to sposób na tworzenie SQL, który w rzeczywistości jest brzydszy i bardziej skomplikowany niż SQL z bardzo niewielką, jeśli w ogóle, prawdziwą korzyścią. „q.addCompareCondition (TAuthor.YEAR_OF_BIRTH, 1920, Comparator.GREATER);” Nie widzę nic naprawdę innego niż jakiekolwiek inne narzędzie do generowania klas na tabelę. Co oznacza, jak już powiedziałem, istnieje prawie pewne prawdopodobieństwo, że już istnieje lepszy. Pola ciągów generowane przez szablon nie są nawet bliskie włączeniu wyrażeń lambda.
quentin-starin
1
Trochę trudno mi zrozumieć motywację twojej odpowiedzi / komentarza. Nadal uważam, że nie przyjrzałeś się dokładnie przykładom, które podałem (zacytowałeś pierwszy przykład), a twoje porównanie z konkurencyjnymi produktami wydaje mi się niejasne. Celem mojego pytania było uzyskanie konstruktywnej informacji zwrotnej i byłbym wdzięczny za to. Wspominasz o „lepszych narzędziach” i „wyrażeniach lambda”. Czy możesz prosić o opracowanie? Jak jOOQ różni się od wspomnianych narzędzi? W jaki sposób wyrażenia lambda są implementowane w Javie 6 - zanim Oracle może je dodać w Javie 8? Jeszcze raz dziękuję
Lukas Eder,
2

Jednym ze scenariuszy, który sprawiłby, że ten rodzaj interfejsu API byłby odpowiedni jest, gdy potrzebujesz konstruktora SQL niezależnego od bazy danych, którego większość ORM na to nie pozwala. Jedną wielką sytuacją, w której jej potrzebowałem, jest generowanie raportów. Musiałem zbudować SQL w sposób obiektowy i uruchomić ten SQL w różnych bazach danych do testowania. Hibernacja i inne ORM są bardzo zależne od konfiguracji, ograniczając w ten sposób moją konstrukcję SQL, tak że nie mogę łączyć tabeli, w której asocjacja nie istnieje w plikach XML. Ponieważ w module raportów, który opracowuję, możliwe jest jakiekolwiek skojarzenie, szukałem czegoś innego. Potem natknąłem się na JOOQ. To po prostu rozwiązuje mój problem. Potrzebowałem tylko dostępu tylko do odczytu, nigdy nie napotykam bolesnych problemów z debugowaniem, takich jak hibernacja.

Właściwie planuję opracować inny sposób modelowania danych niż wspólny sposób POJO i użyć JOOQ jako jednej z podstaw, która jest warstwą do budowania SQL. Oprócz JOOQ planuję stworzyć bardziej elastyczny sposób modelowania danych / encji przy użyciu HashMaps. Mój projekt umożliwiłby łatwiejszą integrację projektu interfejsu użytkownika i zaplecza w jednym punkcie wejścia, chociaż używałbym różnych warstw do ukończenia frameworka, tak jak powiedzieli powyższe komentarze. JOOQ naprawdę odegra bardzo dobrą rolę, jak w moim własnym projekcie, służy jako jeden z fundamentów lub filarów.

Tak więc kontynuujcie dobrą robotę lukas!

wino
źródło
1

Jeśli dobrze rozumiem twoje narzędzie, mapuje Obiekty bezpośrednio do koncepcyjnego frameworku SQL zamiast mapować Obiekty, które implementują niektóre mapowania do funkcji SQL (ORM), prawie jak ORM - abstrakcja dla większej kontroli naukowej, dzięki czemu można użyć większej liczby funkcji SQL ORM zwykle ci nie dawał?

Nie jestem pewien, jaki problem próbujesz rozwiązać. Ponieważ twoje narzędzie wymaga dogłębnej znajomości SQL, czy ludzie nie będą po prostu używać SQL? Czy to kod, którego chcesz się pozbyć? Lepsze sprawdzanie poprawności zapytań SQL poprzez modelowanie API zamiast prostych ciągów?

Muszę przyznać, że twoje przykłady JOOQ wyglądają jak wersje SQL LISP. Nie jest to zła rzecz :) i widzę, że niektóre zaawansowane rzeczy są interesujące, ale zalety, które wymieniasz, powoli znikają, gdy stajesz się coraz bardziej zaawansowany (bardziej konfiguracyjny, mniej abstrakcyjny, bardziej zakorzeniony w wewnętrznym sanktuarium konkretnego SQL silnik itp.)

Jedną z sugestii, które chciałbym zobaczyć, że tęsknię za większością ORM, jest struktura, która może radzić sobie z obiektami w sposób nierelacyjny, tłumacząc interakcje obiektów na cokolwiek to może być backend (SQL, NoSQL, mapy tematów, RDF itp. .), który wymaga buforowania używanego modelu, a nie specyfiki interakcji SQL, dialektów i myślenia relacyjnego.

Oczywiście IMHO. :)

AlexanderJohannesen
źródło
Cześć, dzięki za opinie. Masz rację. Jak to ujął qstarin, staram się usunąć „O” z ORM i pozostać relacyjnym. Dlaczego nie zwykły SQL? Masz na myśli JDBC? Czy zdarzyło Ci się kiedykolwiek przeszukiwać bazę danych za pomocą 5 zagnieżdżonych selekcji i kilku sprzężeń, funkcji analitycznych z JDBC? Błędy składniowe, niedopasowanie wiązania itp. Niestety, jOOQ nie może być dla Ciebie odpowiednim narzędziem, ponieważ nie ma możliwości odwzorowania ŻADNEGO modelu na obiekty. Nie chcę tego. JOOQ POWINIEN być relacyjny. Dla programistów, którzy preferują taki sposób myślenia. Dla innych polecam JPA .. Lub Linq, jeśli robisz .NET
Lukas Eder