Vlad Mihalcea

Laatst gewijzigd:

stel je voor dat je een tool hebt die automatisch JPA en Hibernate prestatieproblemen kan detecteren. Hypersistence Optimizer is dat Gereedschap!

Inleiding

als u zich afvraagt waarom en wanneer u JPA of Hibernate moet gebruiken, dan zal dit artikel u een antwoord geven op deze veel voorkomende vraag. Omdat ik deze vraag heel vaak op het /R/java Reddit kanaal heb gezien, heb ik besloten dat het de moeite waard is om een diepgaand antwoord te schrijven over de sterke en zwakke punten van JPA en Hibernate.

hoewel JPA een standaard is sinds het voor het eerst werd uitgebracht in 2006, is het niet de enige manier waarop je een data access layer kunt implementeren met behulp van Java. We gaan de voor-en nadelen bespreken van het gebruik van PPV of andere populaire alternatieven.

waarom en wanneer JDBC werd opgericht

in 1997, Java 1.1 introduceerde de JDBC (Java Database Connectivity) API, die was zeer revolutionair voor zijn tijd, omdat het was het aanbieden van de mogelijkheid van het schrijven van de data access layer eenmaal met behulp van een set van interfaces en voer het uit op een relationele database die de JDBC API implementeert zonder dat u uw applicatie code te veranderen.

de JDBC API bood een Connection interface om de transactiegrenzen te controleren en eenvoudige SQL-statements te maken via de Statement API of voorbereide statements waarmee u parameterwaarden kunt binden via de PreparedStatement API.

dus, ervan uitgaande dat we een post databasetabel hebben en we 100 rijen willen invoegen, is dit hoe we dit doel zouden kunnen bereiken met JDBC:

int postCount = 100;int batchSize = 50;try (PreparedStatement postStatement = connection.prepareStatement(""" INSERT INTO post ( id, title ) VALUES ( ?, ? ) """)) { for (int i = 1; i <= postCount; i++) { if (i % batchSize == 0) { postStatement.executeBatch(); } int index = 0; postStatement.setLong( ++index, i ); postStatement.setString( ++index, String.format( "High-Performance Java Persistence, review no. %1$d", i ) ); postStatement.addBatch(); } postStatement.executeBatch();} catch (SQLException e) { fail(e.getMessage());}

hoewel we gebruik maakten van multi-line tekstblokken en try-with-resources blokken om de PreparedStatement close call te elimineren, is de implementatie nog steeds zeer uitgebreid. Merk op dat de bindparameters beginnen met 1, niet 0 zoals u gewend bent van andere bekende API ‘ s.

om de eerste 10 rijen op te halen, moeten we mogelijk een SQL-query uitvoeren via de PreparedStatement, die een ResultSet geeft die het tabelgebaseerde query-resultaat vertegenwoordigt. Aangezien toepassingen echter hiërarchische structuren gebruiken, zoals JSON of DTOs om ouder-kind associaties weer te geven, moesten de meeste toepassingen de JDBC ResultSet omzetten naar een ander formaat in de laag voor gegevenstoegang, zoals wordt geïllustreerd door het volgende voorbeeld:

int maxResults = 10;List<Post> posts = new ArrayList<>();try (PreparedStatement preparedStatement = connection.prepareStatement(""" SELECT p.id AS id, p.title AS title FROM post p ORDER BY p.id LIMIT ? """)) { preparedStatement.setInt(1, maxResults); try (ResultSet resultSet = preparedStatement.executeQuery()) { while (resultSet.next()) { int index = 0; posts.add( new Post() .setId(resultSet.getLong(++index)) .setTitle(resultSet.getString(++index)) ); } }} catch (SQLException e) { fail(e.getMessage());}

nogmaals, dit is de mooiste manier waarop we dit kunnen schrijven met JDBC omdat we tekstblokken, try-with-resources en een vloeiende API gebruiken om de Post objecten te bouwen.

niettemin is de JDBC API nog steeds zeer uitgebreid en, nog belangrijker, mist het veel functies die nodig zijn bij het implementeren van een moderne datatoegangslaag, zoals:

  • een manier om objecten direct op te halen uit de set query-resultaten. Zoals we in het voorbeeld hierboven hebben gezien, moeten we de ReusltSet herhalen en de kolomwaarden extraheren om de Post objecteigenschappen in te stellen.
  • een transparante manier om batch statements te maken zonder de data access code te moeten herschrijven wanneer wordt overgeschakeld van de standaard niet-batching modus naar het gebruik van batching.
  • ondersteuning voor optimistische vergrendeling
  • een paginering API die de onderliggende database-specifieke Top-N en Next-N query syntaxis

waarom en wanneer Hibernate werd gemaakt

in 1999 bracht Sun J2EE (Java Enterprise Edition) uit, die een alternatief bood voor JDBC, genaamd Entity Beans.

echter, omdat entiteit Beans notoir traag, overcompliceerd en omslachtig waren om te gebruiken, besloot Gavin King in 2001 een ORM framework te creëren dat databasetabellen kon toewijzen aan POJOs (Plain Old Java Objects), en zo werd Hibernate geboren.Omdat Hibernate lichter was dan Entity Beans en minder uitgebreid was dan JDBC, groeide Hibernate steeds populairder en werd het al snel het populairste Java persistence framework, dat JDO, iBatis, Oracle TopLink en Apache Cayenne overwon.

waarom en wanneer is een PPV opgericht?Het Java EE platform besloot om de manier van Hibernate en Oracle TopLink te standaardiseren en zo ontstond JPA (Java Persistence API).

JPA is slechts een specificatie en kan niet op zichzelf worden gebruikt, het verstrekken van slechts een set van interfaces die de standaard persistence API definiëren, die wordt geïmplementeerd door een JPA-provider, zoals Hibernate, EclipseLink, of OpenJPA.

wanneer u JPA gebruikt, moet u de toewijzing definiëren tussen een databasetabel en het bijbehorende Java-entiteitsobject:

@Entity@Table(name = "post")public class Post { @Id private Long id; private String title; public Long getId() { return id; } public Post setId(Long id) { this.id = id; return this; } public String getTitle() { return title; } public Post setTitle(String title) { this.title = title; return this; }}

daarna kunnen we het vorige voorbeeld herschrijven dat 100 post records heeft opgeslagen ziet er als volgt uit:

for (long i = 1; i <= postCount; i++) { entityManager.persist( new Post() .setId(i) .setTitle( String.format( "High-Performance Java Persistence, review no. %1$d", i ) ) );}

om JDBC batch inserts in te schakelen, hoeven we slechts één configuratie-eigenschap te bieden:

<property name="hibernate.jdbc.batch_size" value="50"/>

zodra deze eigenschap is opgegeven, kan Hibernate automatisch overschakelen van niet-batching naar batching zonder dat de toegangscode hoeft te worden gewijzigd.

en om de eerste 10 post rijen op te halen, kunnen we de volgende jpql query uitvoeren:

int maxResults = 10;List<Post> posts = entityManager.createQuery(""" select p from post p order by p.id """, Post.class).setMaxResults(maxResults).getResultList();

als je dit vergelijkt met de JDBC versie, zul je zien dat JPA veel gemakkelijker te gebruiken is.

de voor-en nadelen van het gebruik van JPA en overwinteren

JPA in het algemeen, en overwinteren in het bijzonder, bieden vele voordelen.

  • u kunt entiteiten of DTO ‘ s ophalen. U kunt zelfs hiërarchische ouder-kind Dto-projectie ophalen.
  • u kunt JDBC batching inschakelen zonder de data access code te wijzigen.
  • u hebt ondersteuning voor optimistische vergrendeling.
  • u hebt een pessimistische locking-abstractie die onafhankelijk is van de onderliggende database-specifieke syntaxis, zodat u een lees-en SCHRIJFVERGRENDELING of zelfs een SKIP-LOCK kunt verkrijgen.
  • u heeft een database-onafhankelijke paginering API.
  • u kunt een List waarde geven aan een in query-clausule, zoals uitgelegd in dit artikel.
  • u kunt een sterk consistente caching-oplossing gebruiken waarmee u het primaire knooppunt kunt verwijderen, dat voor rea-write-transacties alleen verticaal kan worden genoemd.
  • u hebt ingebouwde ondersteuning voor audit logging via Hibernate Envers.
  • u hebt ingebouwde ondersteuning voor multitenancy.
  • u kunt een eerste schemascript genereren van de entiteitstoewijzingen met behulp van het Hibernate hbm2ddl-gereedschap, dat u kunt leveren aan een automatisch schema-migratie-gereedschap, zoals Flyway.
  • niet alleen dat u de vrijheid hebt om elke native SQL-query uit te voeren, maar u kunt ook de SqlResultSetMapping gebruiken om de JDBC ResultSet om te zetten in JPA-entiteiten of DTO ‘ s.

de nadelen van het gebruik van JPA en Hibernate zijn de volgende::

  • terwijl aan de slag met JPA is zeer eenvoudig, uitgegroeid tot een expert vereist een aanzienlijke tijd investering, omdat, naast het lezen van de handleiding, je nog steeds moet leren hoe database systemen werken, de SQL standaard evenals de specifieke SQL smaak gebruikt door uw project relatie database.
  • er zijn een aantal minder intuïtieve gedragingen die beginners kunnen verrassen, zoals de flush operation order.
  • de Criteria API is nogal uitgebreid, dus je moet een tool als Codota gebruiken om dynamische query ‘ s gemakkelijker te schrijven.

de algemene gemeenschap en populaire integraties

JPA en Hibernate zijn zeer populair. Volgens de 2018 Java ecosystem report door Snyk, Hibernate wordt gebruikt door 54% van elke Java-ontwikkelaar die samenwerkt met een relationele database.

dit resultaat kan worden ondersteund door Google Trends. Als we bijvoorbeeld de Google-Trends van JPA vergelijken met zijn belangrijkste concurrenten (bijvoorbeeld MyBatis, QueryDSL en jOOQ), kunnen we zien dat JPA vele malen populairder is en geen tekenen vertoont van verlies van zijn dominante marktpositie.

waarom en wanneer JPA moet worden gebruikt

waarom en wanneer JPA

zo populair is, heeft vele voordelen, zoals:

  • de lente Data JPA integratie werkt als een charme. In feite, een van de grootste redenen waarom JPA en Hibernate zijn zo populair is omdat de lente Boot gebruikt voorjaar gegevens JPA, die op zijn beurt gebruikt Hibernate achter de schermen.
  • als u een probleem heeft, is er een goede kans dat deze 30k Hibernate-gerelateerde StackOverflow antwoorden en 16k JPA-gerelateerde StackOverflow antwoorden u van een oplossing zullen voorzien.
  • er zijn 73k Hibernate tutorials beschikbaar. Alleen mijn site alleen biedt meer dan 250 JPA en Hibernate tutorials die je leren hoe je het meeste uit JPA en Hibernate.
  • er zijn ook veel videocursussen die u kunt gebruiken, zoals mijn High-Performance Java Persistence videocursus.
  • er zijn meer dan 300 boeken over overwinteren op Amazon, waaronder ook mijn High-Performance Java Persistence book.

JPA-alternatieven

een van de grootste dingen over het Java-ecosysteem is de overvloed aan hoogwaardige kaders. Als JPA en Hibernate zijn niet een goede pasvorm voor uw use case, kunt u een van de volgende frameworks gebruiken:

  • MyBatis, dat is een zeer lichtgewicht SQL query mapper framework.
  • QueryDSL, waarmee u SQL -, JPA -, Lucene-en MongoDB-queries dynamisch kunt bouwen.
  • jOOQ, dat een Java-metamodel biedt voor de onderliggende tabellen, opgeslagen procedures en functies en waarmee u dynamisch een SQL-query kunt bouwen met behulp van een zeer intuã tieve DSL en op een typeveilige manier.

gebruik dus wat het beste voor u werkt.

Onlineworkshops

als u dit artikel leuk vond, zult u vast genieten van mijn komende 4-daagse x 4-hours High-Performance Java Persistence online Workshop

conclusie

In dit artikel zagen we waarom JPA werd gemaakt en wanneer je het zou moeten gebruiken. Terwijl JPA brengt vele voordelen, Je hebt vele andere hoogwaardige alternatieven te gebruiken als JPA en Hibernate niet het beste werken voor uw huidige applicatie-eisen.

en soms, zoals ik uitlegde in dit gratis voorbeeld van mijn High-Performance Java Persistence book, hoef je niet eens te kiezen tussen JPA of andere frameworks. U kunt JPA eenvoudig combineren met een framework zoals jOOQ om het beste van beide werelden te krijgen.

Transacties en Concurrency Control eBook

High-Performance Java Persistence rocks!
High-Performance Java Persistence online Workshop
Hypersistentie Optimizer rotsen!

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.