JPA a Spring JdbcTemplate [zamknięty]

88

W przypadku nowego projektu JPA jest zawsze zalecanym narzędziem do obsługi danych relacyjnych, czy są scenariusze, w których Spring JdbcTemplate jest lepszym wyborem? Kilka czynników, które należy wziąć pod uwagę w swojej odpowiedzi:

  • nowy schemat bazy danych a wcześniej istniejący schemat i tabele
  • poziom wiedzy programisty
  • łatwość, z jaką można zintegrować się z warstwą pamięci podręcznej danych
  • wydajność
  • inne istotne czynniki do rozważenia?
aem999
źródło
2
Dodatkowym czynnikiem, który warto wziąć pod uwagę, jest standaryzacja.
Eldad Mor

Odpowiedzi:

147

Użyj Spring JdbcTemplate, jeśli nie chcesz uzyskiwać dostępu do schematu bazy danych za pośrednictwem modelu domeny. Używając JdbcTemplate używasz niższego poziomu dostępu, z większą elastycznością, ale prawdopodobnie również bardziej standardowym.

Spring JdbcTemplate może być łatwiejszy w użyciu z egzotycznymi schematami bazy danych i fokusem na procedury składowane. Używając JPA, musisz upewnić się, że schemat bazy danych jest poprawnie odwzorowany na model domeny.

Obie technologie wymagają od programistów znajomości relacyjnych baz danych, języka SQL i transakcji. W przypadku JPA uzyskujesz jednak bardziej ukrytą złożoność.

Według mojej wiedzy JPA jest łatwiejsze do podłączenia do warstw pamięci podręcznej danych, ponieważ fokus obiektowy ułatwia identyfikację, aktualizację i unieważnianie wpisów pamięci podręcznej.

Możesz lepiej dostroić backendy oparte na JdbcTemplate, ale w większości przypadków potrzeba więcej kodu.

Innym aspektem do rozważenia jest to, że chociaż w przypadku JPA otrzymujesz model domeny dla schematu bazy danych, często będziesz musiał użyć dodatkowych klas DTO. Używając JdbcTemplate możesz bezpośrednio operować klasami DTO.

Timo Westkämper
źródło
4
+1 dobry punkt o tym, że deweloperzy muszą znać relacyjną bazę danych, sql i transakcje. JPA pozwoli jednak na traktowanie warstwy trwałości jako obiektów obsługiwanych przez tabele, a nie tylko jako tabele.
Michael Wiles,
@Timo Próbuję to zrozumieć z perspektywy puli połączeń. Czy zatem JPA może mieć źródło danych, takie jak HikarCP, które ma pulę połączeń? Czy też JPA radzi sobie z tym samodzielnie
Joey587,
79

Trochę spóźniłem się z tym postem, ale zwykle używam JdbcTemplate na ORM. Znam SQL (całkiem dobrze) i naprawdę nie chcę być „wyabstrahowany” z mojej bazy danych. Uważam, że przez większość czasu moje aplikacje używają widoków bazy danych, w których rozwijam większość logiki biznesowej. Mam poprawnie ułożone warstwowe DAO z implementacjami JdbcTemplate. Wydaje się "czysty", a większość gotowego kodu jest ukryta przez JdbcTemplate (a jego dokumentacja online wydaje się DUŻO lepsza niż rzeczy ORM). Przez ograniczony czas użyłem czegoś takiego jak Hibernacja, stwierdziłem, że kiedy to zadziałało, zaoszczędziło mi to trochę czasu ... ale kiedy nie działało poprawnie, kosztowało mnie to dni debugowania "WTF". Nigdy nie musiałem spędzać więcej niż 20 minut na debugowaniu implsów JdbcTemplate DAO. Myślę, że kluczem, jak zauważyli inni, jest wygoda korzystania z SQL / Schema Design

Jason
źródło
49

Zgadzam się z @Timo. Jedyne inne spostrzeżenie, które chciałbym dodać / rozwinąć, to fakt, że ORM ma inną semantykę niż czysty dostęp SQL do twoich danych.

Celem ORM jest abstrahowanie od faktu, że twoje dane w ogóle znajdują się w bazie danych, tak bardzo, jak to możliwe. Kiedy prawidłowo używasz ORM, wszystkie operacje utrwalania są obsługiwane w jednej (miejmy nadzieję) cienkiej warstwie. Twoje obiekty modelu będą miały niewielki lub żaden kod trwałości; fakt, że używasz ORM, powinien być niewidoczny dla twojego modelu.

Z tego powodu ORM bardzo dobrze ułatwia życie w przypadku niektórych rodzajów operacji, a mianowicie prostych operacji CRUD. Możesz ładować obiekty modelu, prezentować je, aktualizować, usuwać w dość łatwy sposób. Ułatwia to życie, ponieważ uzyskując dostęp do danych, otrzymujesz z powrotem obiekty modelu, na których możesz napisać logikę biznesową. Jeśli używasz JDBC, będziesz musiał `` uwodnić '' instancje obiektów na podstawie danych, co może być skomplikowane i podatne na błędy.

ORM nie zawsze jest najlepszym wyborem. JPA to narzędzie do pracy, jeśli narzędzie nie jest wystarczające do pracy, będziesz chciał znaleźć lepsze narzędzie. Na przykład miałem scenariusz, w którym musiałem skopiować cały wykres obiektu i zapisać nową kopię tych obiektów. Gdybym używał ORM (tak jak próbowałem to zrobić), musiałem załadować wszystkie obiekty z bazy danych, następnie skopiować je, a następnie zapisać nowe obiekty. Zajęło mi to zbyt dużo czasu.

Lepszym rozwiązaniem było po prostu użycie operacji opartych na jdbc i wywołań sql typu „insert przez select” w celu utworzenia nowych wierszy. Było szybko, kod był prostszy.

Inną rzeczą do rozważenia jest to, że czujesz się komfortowo z JDBC i masz terminy, nie musisz wskakiwać na modę ORM. Klasy Spring JdbcTemplate są niezwykle wydajne i pomocne. Czasami najlepszym narzędziem do pracy jest to, które znasz. Warto zapoznać się z ORM, ale niekoniecznie przy projekcie o wysokich wymaganiach. Jest wiele do nauczenia się i nie jest to trywialne - tak naprawdę wymieniasz jeden zestaw złożoności z innym, wybierając użycie jdbc vs orm.

hvgotcodes
źródło
9
+1 dla instrukcji końcowej. Generalnie jest to decyzja między jdbc a orm, a nie specyficzna dla JPA i JdbcTemplate.
Parvez
2
co ze śladami pamięci? czy jest jakaś duża różnica między JdbcTemplate a Spring-Data-Jpa? (chyba z hibernacją)
brzytwa
36

Nie ma o tym mowy w innych odpowiedziach, ale można używać obu. W mojej aplikacji używam JPA i JdbcTemplate, do operacji typu crud używam JPA, ale do raportowania lub tam, gdzie jest łatwiej, używam jdbcTemplate.

@Repository
public class FooRepository
{
    @PersistenceContext
    private EntityManager entityManager;

    @Autowired(required = true)
    private JdbcTemplate jdbcTemplate;

    public void saveFoo(Foo foo)
    {
         this.entityManager.persist(foo);
    }

    public List<SomeReportPojo> getSomeReport()
    {
         return this.jdbcTemplate.queryForList("SELECT .. ",SomeProjectPojo.class); 
    }
}

Wspaniałą rzeczą w Spring jest to, że tłumaczenie wyjątków JPA do hierarchii wyjątków Spring Dao działa zarówno z JPA, jak i jdbcTemplate. Więc używaj JPA, gdy ma to sens, i jdbcTemplate, gdy ma to sens.

ams
źródło
20
Czy linia getSomeReport()powinna być this.jdbcTemplate. ...raczej niż this.entityManager. ...?
Jan Zyka
Jak zadeklarować komponent bean JdbcTemplate, jeśli nie używasz XML, ale tylko adnotacje? Nie jest to wykonywane automatycznie przez Spring: otrzymuję NoSuchBeanDefinitionException: Nie znaleziono kwalifikującego komponentu bean typu [org.springframework.jdbc.core.JdbcTemplate]
xtian
5

W pracy używamy Hibernate JDBCTemplate, ponieważ ma on większą elastyczność. Ma również lepszą wydajność niż JPA, ponieważ nie „ładujesz” wielu niepotrzebnych danych do swojej aplikacji.
W przypadku JDBCTemplate, twoje umiejętności SQL w znacznym stopniu zapewniają dokładnie to, czego potrzebujesz, z odpowiednią prędkością.

user3131171
źródło
2
Dzień dobry, czy mógłbyś wyjaśnić „hibernuj jdbctemplate”, co to znaczy? Połączenie Hibernate i Spring JDBCTemplate czy coś innego?
qizer