JPA czy natywny SQL z JDBC

0

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?

1

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

0

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).

1

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. :)

0

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

1
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

0

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.

0
  1. 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.
  2. 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.
  3. 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.
  4. Może można ograć zapisy asynchronicznie.
1
Charles_Ray napisał(a):
  1. 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"

0
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.

  1. 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.

  2. Kilka dni temu tutaj był wątek nt masowych insertów (bulk lub batch insert)

  3. Jak skomplikowana jest Twoja dziedzina? Ile encji/tabel ?

1

Jeżeli chcesz rozdzielić odpowiedzialność obsługi danych pomiędzy różne klasy, taki mały CQSR, to:

  1. zrób czyste JPA do zapisu i odczytu.
  2. napuść na to rozwiązanie testy
  3. 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 :)

0

dobra zadam pytanie w inny sposób, bo nie chodzi mi czy uciągnie czy nie.
Czy natywne sql przez JDBC są szybsze niż używanie JPA+jakiegokolwiek ORM? :)

3

JDBC bedzie szybsze w znakomitej wiekszosci przypadkow, jesli chodzi o odpowiedz na Twoje pytanie.
Tylko musisz sobie odpowiedziec na pytanie, czy zysk wydajnosciowy z tego tytulu bedzie wiekszy niz straty z wolniejszego developmentu.

3

Jeżeli robisz tylko i wyłącznie zapytania i wszystkie mapowania wszywasz na sztywno w kod w miejscu tworzenia zapytań, to tak. JDBC będzie szybsze.

0

Dzięki za odpowiedzi :) Wiem że w tym przypadku wydajność będzie kosztem developmentu.

0
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. ;)

0

Ś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

1 użytkowników online, w tym zalogowanych: 0, gości: 1