All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.query.KeyedPage Maven / Gradle / Ivy

There is a newer version: 6.6.2.Final
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later
 * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
 */
package org.hibernate.query;

import org.hibernate.Incubating;
import org.hibernate.Internal;

import java.util.List;

import static java.util.Collections.unmodifiableList;
import static org.hibernate.query.KeyedPage.KeyInterpretation.KEY_OF_FIRST_ON_NEXT_PAGE;
import static org.hibernate.query.KeyedPage.KeyInterpretation.KEY_OF_LAST_ON_PREVIOUS_PAGE;
import static org.hibernate.query.KeyedPage.KeyInterpretation.NO_KEY;

/**
 * Support for pagination based on a unique key of the result
 * set instead of the {@link Page#getFirstResult() offset}.
 * 

* In this context, a key is a unique key of the * query result set which imposes a total order on the results. * It is represented as a {@code List>} where * {@code R} is the result type of the query. For example, a * unique key for paginating a query result set containing * {@code Book}s might be: *

 * var key = List.of(asc(Book_.title), asc(Book_.publicationDate), asc(Book_.publisher));
 * 
*

* When key-based pagination is used, Hibernate modifies the * original HQL or criteria query to incorporate the key in * the {@code order by}, {@code where}, and {@code select} * clauses. *

* A specification for an initial page may be obtained from * an instance of {@link Page}. *

 * KeyedPage<Book> firstPage = Page.first(10).keyedBy(asc(Book_.isbn)));
 * 
* A {@link KeyedResultList} then may be obtained by calling * {@link SelectionQuery#getKeyedResultList(KeyedPage)}. *
 * KeyedResultList results =
 *         session.createQuery("from Book", Book.class)
 *                .getKeyedResultList(firstPage);
 * 
* The following page may be obtained from {@link KeyedResultList#getNextPage()}. *
 * KeyedPage<Book> nextPage = results.getNextPage();
 * KeyedResultList moreResults =
 *         session.createQuery("from Book", Book.class)
 *                .getKeyedResultList(nextPage);
 * 
*

* A parameter of a {@linkplain org.hibernate.annotations.processing.Find * finder method} or {@linkplain org.hibernate.annotations.processing.HQL * HQL query method} may be declared with type {@code Page}. Then the * return type of the method should be {@link KeyedResultList}. * * @since 6.5 * * @see SelectionQuery#getKeyedResultList(KeyedPage) * @see KeyedResultList * * @author Gavin King */ @Incubating public class KeyedPage { private final List> keyDefinition; private final Page page; private final List> key; private final KeyInterpretation keyInterpretation; KeyedPage(List> keyDefinition, Page page) { this( keyDefinition, page, null, NO_KEY ); } KeyedPage(List> keyDefinition, Page page, List> key, KeyInterpretation interpretation) { this.keyDefinition = unmodifiableList(keyDefinition); this.page = page; this.key = key; this.keyInterpretation = interpretation; } /** * A key definition for key-based pagination. The list of {@link Order} * objects must define a total ordering of the query result set, and * thus forms a unique key on the result set. */ public List> getKeyDefinition() { return keyDefinition; } /** * A specification of this page in terms of page size and an * (approximate) page number. */ public Page getPage() { return page; } /** * The key of the last result on the previous page, or of the * first result on the next page, which may be used to locate * the start or end, respectively, of the current page. *

* A null key indicates that an {@linkplain Page#getFirstResult() * offset} should be used instead. This is used to obtain an * initial page of results. * * @return the key, or null if an offset should be used */ public List> getKey() { return key; } /** * Determines whether the {@link #getKey() key} should be * interpreted as the last result on the previous page, or * as the first result on the next page. */ public KeyInterpretation getKeyInterpretation() { return keyInterpretation; } /** * Obtain a specification of the next page of results, which is * to be located using the given key, which must be the key of * the last result on this page. * * @param keyOfLastResultOnThisPage the key of the last result on this page * @return a {@link KeyedPage} representing the next page of results */ @Internal public KeyedPage nextPage(List> keyOfLastResultOnThisPage) { return new KeyedPage<>( keyDefinition, page.next(), keyOfLastResultOnThisPage, KEY_OF_LAST_ON_PREVIOUS_PAGE ); } /** * Obtain a specification of the previous page of results, which * is to be located using the given key, which must be the key of * the first result on this page. * * @param keyOfFirstResultOnThisPage the key of the first result on this page * @return a {@link KeyedPage} representing the next page of results */ @Internal public KeyedPage previousPage(List> keyOfFirstResultOnThisPage) { if ( page.isFirst() ) { return null; } else { return new KeyedPage<>( keyDefinition, page.previous(), keyOfFirstResultOnThisPage, KEY_OF_FIRST_ON_NEXT_PAGE ); } } /** * Attach the given key to the specification of this page, * with the given interpretation. * * @return a {@link KeyedPage} representing the same page * of results, but which may be located using the * given key */ @Internal public KeyedPage withKey(List> key, KeyInterpretation interpretation) { return new KeyedPage<>( keyDefinition, page, key, interpretation ); } public enum KeyInterpretation { KEY_OF_LAST_ON_PREVIOUS_PAGE, KEY_OF_FIRST_ON_NEXT_PAGE, NO_KEY } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy