JPA vs Spring JdbcTemplate [geschlossen]

84

Ist JPA für ein neues Projekt immer das empfohlene Tool für den Umgang mit relationalen Daten, oder gibt es Szenarien, in denen Spring JdbcTemplate die bessere Wahl ist? Einige Faktoren, die Sie in Ihrer Antwort berücksichtigen sollten:

  • neues Datenbankschema im Vergleich zu bereits vorhandenen Schemata und Tabellen
  • Niveau der Entwicklerkompetenz
  • Leichtigkeit, mit der in eine Daten-Caching-Schicht integriert werden kann
  • Performance
  • irgendwelche anderen relevanten Faktoren zu berücksichtigen?
aem999
quelle
2
Ein weiterer Faktor, den Sie berücksichtigen möchten, ist die Standardisierung.
Eldad Mor

Antworten:

144

Verwenden Sie Spring JdbcTemplate, wenn Sie nicht über ein Domänenmodell auf Ihr Datenbankschema zugreifen möchten. Mit JdbcTemplate verwenden Sie einen Zugriff auf niedrigerer Ebene mit mehr Flexibilität, aber wahrscheinlich auch mehr Boilerplate.

Spring JdbcTemplate kann einfacher mit exotischen Datenbankschemata und einem Fokus auf gespeicherte Prozeduren verwendet werden. Mit JPA müssen Sie sicherstellen, dass das Datenbankschema dem Domänenmodell korrekt zugeordnet ist.

Für beide Technologien müssen Entwickler relationale Datenbanken, SQL und Transaktionen kennen. Mit JPA erhalten Sie jedoch mehr versteckte Komplexität.

JPA lässt sich meines Wissens leichter in Daten-Caching-Ebenen einbinden, da der objektorientierte Fokus die Identifizierung, Aktualisierung und Ungültigmachung von Cache-Einträgen erleichtert.

Sie können JdbcTemplate-basierte Backends besser optimieren, aber in den meisten Fällen ist mehr Code erforderlich.

Ein weiterer zu berücksichtigender Aspekt ist, dass Sie mit JPA zwar ein Domänenmodell für Ihr Datenbankschema erhalten, jedoch häufig zusätzliche DTO-Klassen verwenden müssen. Mit JdbcTemplate können Sie direkt mit DTO-Klassen arbeiten.

Timo Westkämper
quelle
4
+1 guter Punkt für Entwickler, die relationale Datenbanken, SQL und Transaktionen kennen müssen. Mit JPA können Sie Ihre Persistenzschicht jedoch als Objekte behandeln, die von Tabellen unterstützt werden, und nicht nur als Tabellen.
Michael Wiles
@ Timo Ich versuche dies mit einer Verbindungspoolperspektive zu verstehen. Kann ein JPA also eine Datenquelle wie HikarCP haben, die über Verbindungspooling verfügt? Oder erledigt JPA das alleine
Joey587
76

Ich bin etwas spät dran, aber ich neige dazu, JdbcTemplate über ORM zu verwenden. Ich kenne SQL (ziemlich gut) und möchte wirklich nicht von meiner Datenbank "abstrahiert" werden. Ich finde, dass meine Apps die meiste Zeit DB-Ansichten verwenden, auf die ich die meiste Geschäftslogik übertrage. Ich habe DAOs mit JdbcTemplate-Implementierungen richtig geschichtet. Es fühlt sich "sauber" an und der meiste Boilerplate-Code wird von JdbcTemplate versteckt (und die Online-Dokumentation scheint VIEL besser zu sein als ORM-Zeug). Die begrenzte Zeit, in der ich so etwas wie "Ruhezustand" verwendet habe, hat mir Zeit gespart, aber wenn es nicht richtig funktioniert hat, hat es mich Tage des "WTF" -Debuggens gekostet. Ich musste nie mehr als 20 Minuten damit verbringen, JdbcTemplate DAO-Impls zu debuggen. Ich denke, der Schlüssel ist, wie andere angemerkt haben, wie gut Sie mit SQL / Schema Design vertraut sind

Jason
quelle
48

Ich stimme @Timo zu. Die einzige andere Erkenntnis, die ich hinzufügen / erweitern möchte, ist, dass ORM eine andere Semantik hat als der reine SQL-Zugriff auf Ihre Daten.

Der Zweck von ORM besteht darin, die Tatsache, dass sich Ihre Daten überhaupt in einer Datenbank befinden, so weit wie möglich zu abstrahieren. Wenn Sie ORM richtig verwenden, werden alle Persistenzoperationen in einer (hoffentlich) dünnen Schicht behandelt. Ihre Modellobjekte haben wenig bis keinen Persistenzcode. Die Tatsache, dass Sie ORM verwenden, sollte für Ihr Modell unsichtbar sein.

Aus diesem Grund ist ORM sehr gut darin, Ihnen das Leben für bestimmte Arten von Operationen zu erleichtern, nämlich für einfache CRUD-Operationen. Sie können Ihre Modellobjekte ganz einfach laden, präsentieren, aktualisieren und löschen. Dies erleichtert Ihnen das Leben, da Sie beim Zugriff auf Ihre Daten Modellobjekte zurückerhalten, auf die Sie Geschäftslogik schreiben können. Wenn Sie JDBC verwenden, müssen Sie Ihre Objektinstanzen aus den Daten "hydratisieren", was kompliziert und fehleranfällig sein kann.

ORM ist nicht immer die beste Wahl. JPA ist ein Werkzeug für einen Job. Wenn das Werkzeug für den Job nicht ausreicht, möchten Sie ein besseres Werkzeug finden. Zum Beispiel hatte ich ein Szenario, in dem ich ein gesamtes Objektdiagramm kopieren und eine neue Kopie dieser Objekte speichern musste. Wenn ich ORM verwendet hatte (wie ich es versucht hatte), musste ich alle Objekte aus der Datenbank laden, sie kopieren und dann die neuen Objekte speichern. Ich habe viel zu lange gebraucht.

Die bessere Lösung bestand einfach darin, jdbc-basierte Operationen zu verwenden und SQL-Aufrufe über Select einzufügen, um die neuen Zeilen zu erstellen. Es war schnell, der Code war einfacher.

Die andere zu berücksichtigende Sache ist, dass Sie mit JDBC vertraut sind und Fristen haben, Sie müssen nicht auf den ORM-Zug springen. Die Spring JdbcTemplate-Klassen sind äußerst leistungsfähig und hilfreich. Manchmal ist das beste Werkzeug für den Job das, das Sie kennen. Sie sollten sich mit ORM vertraut machen, aber nicht unbedingt für ein Projekt mit hohen Erwartungen. Es gibt viel zu lernen und es ist nicht trivial - wirklich tauschen Sie eine Reihe von Komplexitäten mit einer anderen aus, wenn Sie sich für jdbc vs orm entscheiden.

hvgotcodes
quelle
9
+1 für die Endanweisung. Es ist im Allgemeinen eine Entscheidung zwischen jdbc vs orm und nicht spezifisch für JPA vs JdbcTemplate.
Parvez
2
Was ist mit dem Speicherbedarf? Gibt es einen großen Unterschied zwischen JdbcTemplate und Spring-Data-Jpa? (mit Winterschlaf, denke ich)
Rasiermesser
36

Es wird in den anderen Antworten nicht erwähnt, aber es ist in Ordnung, beide zu verwenden. In meiner App verwende ich JPA und JdbcTemplate, für grobe Operationen verwende ich JPA, aber für die Berichterstellung oder wo es einfacher ist, verwende ich 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); 
    }
}

Das Tolle an Spring ist, dass die Ausnahmeübersetzung von JPA-Ausnahmen in die Dao-Ausnahmehierarchie von Spring sowohl mit JPA als auch mit jdbcTemplate funktioniert. Verwenden Sie also JPA, wenn es Sinn macht, und jdbcTemplate, wenn es Sinn macht.

ams
quelle
20
Sollte die Linie in getSomeReport()sein this.jdbcTemplate. ...statt this.entityManager. ...?
Jan Zyka
Wie deklarieren Sie die JdbcTemplate-Bean, wenn Sie nicht XML, sondern nur Anmerkungen verwenden? Es wird nicht automatisch von Spring gemacht: Ich bekomme NoSuchBeanDefinitionException: Keine qualifizierende Bean vom Typ [org.springframework.jdbc.core.JdbcTemplate] gefunden
xtian
5

Bei der Arbeit verwenden wir Hibernate JDBCTemplate, weil es flexibler ist. Es hat auch eine bessere Leistung als JPA, da Sie nicht viele unnötige Daten in Ihre App "laden".
Im Fall JDBCTemplate tragen Ihre SQL-Kenntnisse wesentlich dazu bei, dass Sie genau das bekommen, was Sie mit der richtigen Geschwindigkeit benötigen.

user3131171
quelle
1
Guten Tag, könnten Sie bitte "Ruhezustand jdbctemplate" klären, was bedeutet das? Kombination von Hibernate und Spring JDBCTemplate oder etwas anderes?
Qizer