Kiedy używać JPA a kiedy natywnego SQL z JDBC? Powiedzmy mamy system który ma szybko zapisywać do bazy i jakąś warstwę prezentującą wyniki w takim przypadku powinniśmy użyć natywnego SQL z JDBC czyli dla każdej "encji" mieć składanie INSERTA? natomiast warstwa prezentująca może już używać JPA?
- Rejestracja:prawie 7 lat
- Ostatnio:około miesiąc
- Postów:3561
Jest wiele opcji pośrednich, również lekkie mapery SQL<->obiekt: JDBI, JOOQ, Deltaspike i kilka innych,
darksead napisał(a):
natomiast warstwa prezentująca może już używać JPA?
Skoro JPA nie było potrzebne niżej, to wyżej tym bardziej. Na minus w prezentacji niuanse JPA mogą zdrowo kopać, na plus nie ma żadnych argumentów
- Rejestracja:ponad 8 lat
- Ostatnio:8 miesięcy
- Postów:145
Chodzi mi bardziej o wydajność zapisu jak wiadomo natywny sql bez zbędnej jakiejkolwiek otoczki chyba będzie najszybszy? Czyli tworzenie stringowych INSERTOW dla kazdego z obiektu?
Co do zapytań to JPA moze byc przydatny w przypadku wykonywać tych samych zapytań (cache).

- Rejestracja:około 6 lat
- Ostatnio:ponad 2 lata
- Postów:58
Generalnie, JPA raczej ułatwia operacje na pojedynczych rekordach i najlepiej się sprawdza, wg mnie, w przypadkach, gdy są to operacje modyfikujące rekordy.
Do wyświetlania lepiej korzystać z dopasowanych zapytań i obiektów, bo przy nieco bardziej skomplikowanej strukturze zamiast przygotowywać kolejne dane do prezentacji, będziesz bił się z JPA.
Ostatnio korzystałem z SimpleFlatMapper do mapowania wyników zaytań z wykorzystaniem Springowego JdbcTemplate (SFM - Spring JDBC). Całkiem przyjemnie się używało.
darksead napisał(a):
Chodzi mi bardziej o wydajność zapisu jak wiadomo natywny sql bez zbędnej jakiejkolwiek otoczki chyba będzie najszybszy? Czyli tworzenie stringowych INSERTOW dla kazdego z obiektu?
Co do zapytań to JPA moze byc przydatny w przypadku wykonywać tych samych zapytań (cache).
Jeśli korzystasz ze Springa, możesz skorzystać ze Spring Cache + np. Hazelcast. Ew. sam możesz zarządzać cache, ale domyślam się, że nie chcesz tego robić, dlatego to pytanie. :)
- Rejestracja:prawie 7 lat
- Ostatnio:około miesiąc
- Postów:3561
Jest taki sposób na zbudowanie aplikacji CQRS, że zapis odbywa się przez inne moduły niż odczyt.
Jednak czegoś "ambitniejszego" w rodzaju JPA używa się do zapisu, aby logika JPA pozwalała to bezpiecznie zrealizować, a odczyt przez natywne, aby ręczne kwerendy były szybsze, albo aby wybierać tylko potrzebne pola. Zgadzam się z @catom
Nie demonizujmy, że zapis JPA musi mieć koszmarną wydajność, to zależy. Opisz z czym masz problem
- Rejestracja:prawie 7 lat
- Ostatnio:około miesiąc
- Postów:3561
darksead napisał(a):
Chodzi mi bardziej o wydajność zapisu jak wiadomo natywny sql bez zbędnej jakiejkolwiek otoczki chyba będzie najszybszy? Czyli tworzenie stringowych INSERTOW dla kazdego z obiektu?
"jak wiadomo" ???
Co do zapytań to JPA moze byc przydatny w przypadku wykonywać tych samych zapytań (cache).
Encje JPA są dość trudnym obywatelem w cache, i nie wiadomo czy na tym skorzystasz
- Rejestracja:ponad 8 lat
- Ostatnio:8 miesięcy
- Postów:145
Zastanawia mnie wydjaność zapisu danych z JPA, bo JPA musi jakoś te encje przerobić na inserta czyli lata refleksją więc ręczne składanie insertów będzie szybsze bo będzie przy pomocy "getterów", w module zapisujacym nie potrzebuje żadnego cache'owania. Wszystkie te mappery w jakimś stopniu spowalniają zapis bo muszą skanować obiekt i wybierać wartości refleksją. System nad którym pracuje może przyjąć nawet 20mln wpisów dziennie.

- Rejestracja:około 17 lat
- Ostatnio:około 24 godziny
- Postów:1875
- 20 mln dziennie - ile to operacji na sekundę w peeku? Może się okaże, że Hibernate to dźwignie. Może warto zrobić POC.
- Generalnie stosując jakiegokolwiek ORM masz trade-off mapowania obiektowo-relacyjnego i dirty-checking VS. wydajność zarówno read jak i write. Zwykle warto rozważyć implementację odczytów w oparciu o natywnego SQL, ponieważ i tak dane nie będą modyfikowane + możesz skorzystać z widoku itp.
- Może zapisy są "proste", nie ma jakichś skomplikowanych modyfikacji tych danych, model nie jest obiektowy (nie musi być) i wykorzystanie ORM w ogóle będzie znikome - wtedy można odpuścić JPA.
- Może można ograć zapisy asynchronicznie.
- Rejestracja:prawie 7 lat
- Ostatnio:około miesiąc
- Postów:3561
Charles_Ray napisał(a):
- Generalnie stosując jakiegokolwiek ORM masz trade-off mapowania obiektowo-relacyjnego i dirty-checking VS. wydajność zarówno read jak i write. Zwykle warto rozważyć implementację odczytów w oparciu o natywnego SQL, ponieważ i tak dane nie będą modyfikowane + możesz skorzystać z widoku itp.
Jakbyś wszedł w "lekkie" mapery top byś tak nie pisał. One NIC nie robią w zakresie dirty checking, żadnej magii z relacjami, żadne skomplikowanej "sesji"
- Rejestracja:prawie 7 lat
- Ostatnio:około miesiąc
- Postów:3561
darksead napisał(a):
Zastanawia mnie wydjaność zapisu danych z JPA, bo JPA musi jakoś te encje przerobić na inserta czyli lata refleksją więc ręczne składanie insertów będzie szybsze bo będzie przy pomocy "getterów", w module zapisujacym nie potrzebuje żadnego cache'owania. Wszystkie te mappery w jakimś stopniu spowalniają zapis bo muszą skanować obiekt i wybierać wartości refleksją. System nad którym pracuje może przyjąć nawet 20mln wpisów dziennie.
-
Nie spodziewaj się naiwnego użycia refleksji. Klasy są (w różny sposób) przygotowywane jednorazowo przy starcie programu lub Persistence Unit. Różne providery (Hibernate, ja lubię Eclipselink) mają różne smaczki.
-
Kilka dni temu tutaj był wątek nt masowych insertów (bulk lub batch insert)
-
Jak skomplikowana jest Twoja dziedzina? Ile encji/tabel ?
Jeżeli chcesz rozdzielić odpowiedzialność obsługi danych pomiędzy różne klasy, taki mały CQSR, to:
- zrób czyste JPA do zapisu i odczytu.
- napuść na to rozwiązanie testy
- najprawdopodobniej wdrożysz na produkcję, bo będzie OK.
Przy czym musisz zrozumieć, jak działa JPA i jakie jego mechanizmy możesz użyć przy tworzeniu kodu. Batch/bulk insert, to jedne z mechanizmów. Przy odczycie przydatne mogą okazać się construction queries, by tworzyć agregaty. I najważniejsze zmierz to, co robisz. Inaczej zaczniesz opisywać problemy w dziale SQL :)
- Rejestracja:ponad 6 lat
- Ostatnio:16 dni
- Postów:259
dargenn napisał(a):
Tylko musisz sobie odpowiedziec na pytanie, czy zysk wydajnosciowy z tego tytulu bedzie wiekszy niz straty z wolniejszego developmentu.
W większości przypadków raczej: czy zysk będzie miał jakiekolwiek znaczenie w porównaniu ze skutkami sp...nej struktury fizycznej po stronie bazy danych. ;)
- Rejestracja:prawie 7 lat
- Ostatnio:około miesiąc
- Postów:3561
Świeża anegdota z życia, z morałem
Do instalacji 'biznesowej' której jestem 'ojcem', by nie powiedzieć głównym projektantem, kilka lat temu dopuściłem podwykonawcę/kolegę.Ponieważ uprawia język odchodzący w niszę, postanowiliśmy, że będzie insertował do surowej tabeli. Co do reguł biznesowych obiecaliśmy, że "będziemy pamiętać i uważać". Właśnie serwisuję bazę MSSQL, bo dokument który miał się nie zrobić w niedzielę, jednak się dał zrobić, w tym wdrożeniu akurat na to DUŻE znaczenie. Naruszenie zasad biznesowych - kilka lat później - się stało mimo obietnic.
Morał: ja Cię proszę ;) użyj klas i lekkiego mapera,ale utrzymaj kontrolę logiczną. Po załadowaniu klas, spreparowaniu SQL-i i rozgrzaniu się na pierwszych rekordach będziesz miał czas nieodróżnialny od surowego JDBC, ale większą kontrolę logiczną
UPDATE: https://github.com/bwajtr/java-persistence-frameworks-comparison
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.
@Embbeded
,@SecondaryTables
/(s
) czy ww. construction queries, to rzadkość. Do tego masz jeszcze konwertery i możliwość zmiany nazw atrybutów. A pomimo tego i tak większość projektów próbuje robić OOP w bazie lub relacyjność w modelu OO.@Embbeded
znam i korzystałem z reszty nie. W każdym razie dzięki doczytam sobie.