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ć.
Odpowiedzi:
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.
źródło
„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.
źródło
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!
źródło
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. :)
źródło