Java >> Java tutorial >  >> Tag >> hibernate

Hibernate SQM – Semantisk forespørgselsmodel

Introduktion

I denne artikel vil jeg forklare, hvad Hibernate SQM eller Semantic Query Model er, så du har et bedre billede af, hvordan JPQL eller Criteria API-forespørgsler udføres af Hibernate.

Dvale 5, 4 og 3

Før Hibernate 6 blev enhedsforespørgsler udført som følger:

Criteria API ville simpelthen generere en JPQL, som Hibernate parsede i henhold til dens HQL-grammatik for at generere den underliggende databasespecifikke SQL-forespørgsel.

At lade Criteria API generere JPQL, kun for senere at blive parset, er det ikke særlig effektivt, så en bedre model blev designet til at håndtere disse entitetsforespørgsler.

Hibernate 6 SQL – Semantisk forespørgselsmodel

Startende med Hibernate 6, er det sådan, entitetsforespørgsler genereres:

JPQL kompileres til SQM, mens Criteria API'en skabte SQM-noderne med det samme, hvilket forbedrer dens effektivitet.

For at se, hvordan SQM er bygget, skal du indstille org.hibernate.orm.query.sqm.ast logger til debug niveau:

<logger name="org.hibernate.orm.query.sqm.ast" level="debug"/>

Og når du udfører følgende JPQL Window Functions-forespørgsel:

List<StatementRecord> records = entityManager.createQuery("""
    SELECT
       ROW_NUMBER() OVER(       
           PARTITION BY at.account.id
           ORDER BY at.createdOn   
       ) AS nr,
       at,
       SUM(at.amount) OVER(       
           PARTITION BY at.account.id
           ORDER BY at.createdOn   
       ) AS balance
    FROM AccountTransaction at
    ORDER BY at.id
    """, StatementRecord.class)
.unwrap(Query.class)
.setTupleTransformer((Object[] tuple, String[] aliases) -> new StatementRecord(
    longValue(tuple[0]),
    (AccountTransaction) tuple[1],
    longValue(tuple[2])
))
.getResultList();

Hibernate vil logge følgende semantiske forespørgselsmodeltræ:

o.h.o.q.s.ast - SqmStatement Tree :
-> [select]
  -> [query-spec]
    -> [select]
      -> [selection(nr)]
      <- [selection(nr)]
      -> [selection]
        -> [root] - `com.vladmihalcea.book.hpjp.hibernate.query.window.AccountTransaction(at)`
        <- [root] - `com.vladmihalcea.book.hpjp.hibernate.query.window.AccountTransaction(at)`
      <- [selection]
      -> [selection(balance)]
      <- [selection(balance)]
    <- [select]
    -> [from]
      -> [root] - `com.vladmihalcea.book.hpjp.hibernate.query.window.AccountTransaction(at)`
      <- [root] - `com.vladmihalcea.book.hpjp.hibernate.query.window.AccountTransaction(at)`
    <- [from]
  <- [query-spec]
<- [select]

Hibernate 6 SqmSelectStatement klasse implementerer Jakarta Persistence TypedQuery og CriteriaQuery og har følgende afhængigheder:

Ved at forene forespørgselsmodellen vil Hibernate 6 Criteria-forespørgslerne kunne udvides med funktioner, der ikke understøttes af en given Jakarta Persistence-specifikation, ligesom Hibernate HQL giver flere funktioner end standard JPQL-specifikationen.

Konklusion

Hibernate 6 giver en masse nye funktioner, og den nye SQM (Semantic Query Model) er en meget kraftfuld API, der er grundlaget for mange nye forespørgselsfunktioner.

Med Hibernate SQM API på plads kan Hibernate levere avancerede forespørgselsfunktioner, som tidligere er blevet leveret af Blaze Persistence, såsom LATERAL JOINs, CTE (Common Table Expressions) eller Window Functions.


Java tag