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

Den bedste måde at bruge Hibernate TupleTransformer på

Introduktion

I denne artikel vil jeg forklare, hvordan Hibernate TupleTransformer fungerer, og hvordan man bruger den til at erstatte den forældede ResultTransformer.

Den forældede ResultTransformer

Før du bruger Hibernate 6, er ResultTransformer var standardindstillingen til at transformere et forespørgselsresultatsæt.

Men siden 5.2 er setResultTransformer metoden for Hibernate Query grænsefladen blev forældet, selvom der ikke var noget alternativ på det tidspunkt. Grunden til, at denne metode og dens tilknyttede ResultTransformer grænsefladen blev forældet var, at ResultTransformer grænsefladen var ikke en funktionel grænseflade.

En funktionel grænseflade giver en enkelt abstrakt metode og kan bruges til at definere et lambda-udtryk. Af denne grund er den gamle ResultTransformer grænsefladen blev opdelt i to grænseflader TupleTransformer og ResultListTransformer , som illustreret i følgende diagram:

Hibernate TupleTransformer

TupleTransformer definerer transformTuple metode som følger:

@Incubating
@FunctionalInterface
public interface TupleTransformer<T> {
    /**
     * Tuples are the elements making up each "row" of the query result.
     * The contract here is to transform these elements into the final
     * row shape.
     *
     * @param tuple The result elements
     * @param aliases The result aliases ("parallel" array to tuple)
     *
     * @return The transformed row.
     */
    T transformTuple(Object[] tuple, String[] aliases);
}

transformTuple metode giver dig mulighed for at transformere standard Object[] matrixprojektion som følge af JDBC ResultSet efter at have forbrugt en given post.

Sådan bruger du Hibernate TupleTransformer

Lad os f.eks. sige, at vi har følgende Post enhed:

@Entity(name = "Post")
@Table(name = "post")
public class Post {

    @Id
    private Long id;

    private String title;

    @Column(name = "created_on")
    private LocalDateTime createdOn;

    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "updated_on")
    private LocalDateTime updatedOn;

    @Column(name = "updated_by")
    private String updatedBy;

    @Version
    private Integer version;
}

Og vi ønsker at udføre følgende JPQL-forespørgsel, som henter en brugerdefineret projektion:

select 
    p.id,
    p.title,
    p.createdOn,
    p.createdBy,
    p.updatedOn,
    p.updatedBy
from Post p
order by p.id

Som standard, når JPQL-forespørgslen ovenfor udføres, vil projektposterne blive pakket ind i en Object[] array:

List<Object[]> postRecords = entityManager.createQuery("""
    select 
        p.id,
        p.title,
        p.createdOn,
        p.createdBy,
        p.updatedOn,
        p.updatedBy
    from Post p
    order by p.id
    """)
.getResultList();

Men arbejder med Object[] array-projektioner er ikke udviklervenlige, så vi ønsker at kortlægge forespørgselsresultatet på følgende Java Record-hierarki:

Til dette formål vil vi bruge en TupleTransformer der giver os mulighed for at kortlægge standarden Object[] array-projektion til PostRecord objekt, som dette:

List<PostRecord> postRecords = entityManager.createQuery("""
    select 
        p.id,
        p.title,
        p.createdOn,
        p.createdBy,
        p.updatedOn,
        p.updatedBy
    from Post p
    order by p.id
    """)
.unwrap(org.hibernate.query.Query.class)
.setTupleTransformer(
    (tuple, aliases) -> {
        int i =0;
        return new PostRecord(
            longValue(tuple[i++]),
            stringValue(tuple[i++]),
            new AuditRecord(
                localDateTimeValue(tuple[i++]),
                stringValue(tuple[i++]),
                localDateTimeValue(tuple[i++]),
                stringValue(tuple[i++])
            )
        );
    }
)
.getResultList();

Fedt, ikke?

Konklusion

Hibernate 6 giver en masse nye funktioner, såsom [SQM (Semantic Query Model)(https://vladmihalcea.com/hibernate-sqm-semantic-query-model/) eller support til vinduesfunktioner.

Den nye Hibernate TupleTransformer skal bruges til at erstatte den gamle ResultTransformer brug, som den forældede ResultTransformer vil helt sikkert blive fjernet i en fremtidig version af Hibernate.


Java tag