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

com.blazebit.persistence.FullQueryBuilder Maven / Gradle / Ivy

/*
 * Copyright 2014 - 2020 Blazebit.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.blazebit.persistence;

import javax.persistence.TypedQuery;
import java.lang.reflect.Constructor;

/**
 * A base interface for builders that support normal query functionality.
 * This interface is shared between the criteria builder and paginated criteria builder.
 *
 * @param  The query result type
 * @param  The concrete builder type
 * @author Christian Beikov
 * @since 1.1.0
 */
public interface FullQueryBuilder> extends QueryBuilder, FetchBuilder {

    /**
     * Copies this query builder into a new one, using it's projection as an overridable default.
     *
     * @param resultClass The result class of the query
     * @param  The type of the result class
     * @return A new query builder
     * @since 1.2.0
     */
    public  FullQueryBuilder copy(Class resultClass);

    /**
     * Returns a query that counts the results that would be produced if the current query was run.
     *
     * @return A query for determining the count of the result list represented by this query builder
     * @since 1.2.0
     */
    public TypedQuery getCountQuery();

    /**
     * Returns the query string that selects the count of elements.
     *
     * @return The query string
     * @since 1.3.0
     */
    public String getCountQueryString();

    /**
     * Returns a query that counts the results and counts up to the maximum value that is given that would be produced if the current query was run.
     *
     * @param maximumCount the maximum value up to which should be counted
     * @return A query for determining the count of the result list represented by this query builder
     * @since 1.5.0
     */
    public TypedQuery getCountQuery(long maximumCount);

    /**
     * Returns the query string that selects the count of elements and counts up to the maximum value that is given.
     *
     * @param maximumCount the maximum value up to which should be counted
     * @return The query string
     * @since 1.5.0
     */
    public String getCountQueryString(long maximumCount);

    /**
     * Invokes {@link FullQueryBuilder#pageBy(int, int, String, String...)} with the identifiers of the query root entity.
     *
     * @param firstResult The position of the first result to retrieve, numbered from 0
     * @param maxResults The maximum number of results to retrieve
     * @return This query builder as paginated query builder
     */
    public PaginatedCriteriaBuilder page(int firstResult, int maxResults);

    /**
     * Invokes {@link FullQueryBuilder#pageByAndNavigate(Object, int, String, String...)} with the identifiers of the query root entity.
     *
     * @deprecated This method causes a method resolution ambiguity. Use {{@link #pageAndNavigate(Object, int)}} instead.
     * @param entityId The id of the entity which should be located on the page
     * @param maxResults The maximum number of results to retrieve
     * @return This query builder as paginated query builder
     */
    @Deprecated
    public PaginatedCriteriaBuilder page(Object entityId, int maxResults);

    /**
     * Invokes {@link FullQueryBuilder#pageByAndNavigate(Object, int, String, String...)} with the identifiers of the query root entity.
     *
     * @param entityId The id of the entity which should be located on the page
     * @param maxResults The maximum number of results to retrieve
     * @return This query builder as paginated query builder
     * @since 1.3.0
     */
    public PaginatedCriteriaBuilder pageAndNavigate(Object entityId, int maxResults);

    /**
     * Invokes {@link FullQueryBuilder#pageBy(KeysetPage, int, int, String, String...)} with the identifiers of the query root entity.
     *
     * @param keysetPage The key set from a previous result, may be null
     * @param firstResult The position of the first result to retrieve, numbered from 0
     * @param maxResults The maximum number of results to retrieve
     * @return This query builder as paginated query builder
     * @see PagedList#getKeysetPage()
     */
    public PaginatedCriteriaBuilder page(KeysetPage keysetPage, int firstResult, int maxResults);

    /**
     * Like {@link FullQueryBuilder#pageBy(int, int, String, String...)} but lacks the varargs parameter to avoid heap pollution.
     *
     * @param firstResult The position of the first result to retrieve, numbered from 0
     * @param maxResults The maximum number of results to retrieve
     * @param identifierExpression The first identifier expression
     * @return This query builder as paginated query builder
     * @since 1.3.0
     */
    public PaginatedCriteriaBuilder pageBy(int firstResult, int maxResults, String identifierExpression);

    /**
     * Like {@link FullQueryBuilder#pageByAndNavigate(Object, int, String, String...)} but lacks the varargs parameter to avoid heap pollution.
     *
     * @param entityId The id of the entity which should be located on the page
     * @param maxResults The maximum number of results to retrieve
     * @param identifierExpression The first identifier expression
     * @return This query builder as paginated query builder
     * @since 1.3.0
     */
    public PaginatedCriteriaBuilder pageByAndNavigate(Object entityId, int maxResults, String identifierExpression);

    /**
     * Like {@link FullQueryBuilder#pageBy(KeysetPage, int, int, String, String...)} but lacks the varargs parameter to avoid heap pollution.
     *
     * @param keysetPage The key set from a previous result, may be null
     * @param firstResult The position of the first result to retrieve, numbered from 0
     * @param maxResults The maximum number of results to retrieve
     * @param identifierExpression The first identifier expression
     * @return This query builder as paginated query builder
     * @since 1.3.0
     * @see PagedList#getKeysetPage()
     */
    public PaginatedCriteriaBuilder pageBy(KeysetPage keysetPage, int firstResult, int maxResults, String identifierExpression);

    /**
     * Paginates the results of this query based on the given identifier expressions.
     *
     * In JPA, the use of setFirstResult and setMaxResults is not defined when involving fetch joins for collections.
     * When no collection joins are involved, this is fine as rows essentially represent objects, but when collections are joined, this is no longer true.
     * JPA providers usually fall back to querying all data and doing pagination in-memory based on objects or simply don't support that kind of query.
     *
     * This API allows to specify the identifier expressions to use for pagination and transparently handles collection join support.
     * The big advantage of this API over plain setFirstResult and setMaxResults can also be seen when doing scalar queries.
     * 
     * 

* An example for such queries would be a query that joins a collection: * * SELECT d.id, contacts.name FROM Document d LEFT JOIN d.contacts contacts * * If one Document has associated multiple contacts, the above query will produce multiple result set rows for that document. * Paginating via setFirstResult and setMaxResults would produce unexpected results whereas using this API, will produce the expected results. *

* *

* When paginating on the identifier i.e. d.id, the results are implicitly grouped by the document id and distinct. Therefore calling * distinct() on a PaginatedCriteriaBuilder is not allowed. *

* * @param firstResult The position of the first result to retrieve, numbered from 0 * @param maxResults The maximum number of results to retrieve * @param identifierExpression The first identifier expression * @param identifierExpressions The other identifier expressions * @return This query builder as paginated query builder * @since 1.3.0 */ public PaginatedCriteriaBuilder pageBy(int firstResult, int maxResults, String identifierExpression, String... identifierExpressions); /** * Paginates the results of this query and navigates to the page on which * the object with the given identifier is located. * * Beware that the same limitations like for {@link FullQueryBuilder#page(int, int)} apply. * If the object with the given identifier does not exist in the result list: *
    *
  • The result of {@link PaginatedCriteriaBuilder#getResultList()} will contain the first page
  • *
  • {@link PagedList#getFirstResult()} will return -1
  • *
* * @param entityId The id of the object which should be located on the page * @param maxResults The maximum number of results to retrieve * @param identifierExpression The first identifier expression * @param identifierExpressions The other identifier expressions * @return This query builder as paginated query builder * @since 1.3.0 */ public PaginatedCriteriaBuilder pageByAndNavigate(Object entityId, int maxResults, String identifierExpression, String... identifierExpressions); /** * Like {@link FullQueryBuilder#page(int, int)} but additionally uses key set pagination when possible. * * Beware that keyset pagination should not be used as a direct replacement for offset pagination. * Since entries that have a lower rank than some keyset might be added or removed, the calculations * for the firstResult might be wrong. If strict pagination is required, then the {@link KeysetPage} should * not be used when the count of lower ranked items changes which will result in the use of offset pagination for that request. * *

* Key set pagination is possible if and only if the following conditions are met: *

    *
  • The keyset reference values fit the order by expressions of this query builder AND
  • *
  • {@link KeysetPage#getMaxResults()} and maxResults evaluate to the same value AND
  • *
  • One of the following conditions is met: *
      *
    • The absolute value of {@link KeysetPage#getFirstResult()} - firstResult is 0
    • *
    • The absolute value of {@link KeysetPage#getFirstResult()} - firstResult is equal to the value of * maxResults
    • *
    *
  • *
*

* * @param keysetPage The key set from a previous result, may be null * @param firstResult The position of the first result to retrieve, numbered from 0 * @param maxResults The maximum number of results to retrieve * @param identifierExpression The first identifier expression * @param identifierExpressions The other identifier expressions * @return This query builder as paginated query builder * @since 1.3.0 * @see PagedList#getKeysetPage() */ public PaginatedCriteriaBuilder pageBy(KeysetPage keysetPage, int firstResult, int maxResults, String identifierExpression, String... identifierExpressions); /** * Like calling {@link #pageBy(int, int, String)} and then {@link PaginatedCriteriaBuilder#createPageIdQuery()} but more efficient. * * @param firstResult The position of the first result to retrieve, numbered from 0 * @param maxResults The maximum number of results to retrieve * @param identifierExpression The first identifier expression * @return the {@link CriteriaBuilder} to query id values * @since 1.4.1 */ public CriteriaBuilder createPageIdQuery(int firstResult, int maxResults, String identifierExpression); /** * Like calling {@link #pageBy(KeysetPage, int, int, String)} and then {@link PaginatedCriteriaBuilder#createPageIdQuery()} but more efficient. * * @param keysetPage The key set from a previous result, may be null * @param firstResult The position of the first result to retrieve, numbered from 0 * @param maxResults The maximum number of results to retrieve * @param identifierExpression The first identifier expression * @return the {@link CriteriaBuilder} to query id values * @since 1.4.1 */ public CriteriaBuilder createPageIdQuery(KeysetPage keysetPage, int firstResult, int maxResults, String identifierExpression); /** * Like calling {@link #pageBy(int, int, String, String...)} and then {@link PaginatedCriteriaBuilder#createPageIdQuery()} but more efficient. * * @param firstResult The position of the first result to retrieve, numbered from 0 * @param maxResults The maximum number of results to retrieve * @param identifierExpression The first identifier expression * @param identifierExpressions The other identifier expressions * @return the {@link CriteriaBuilder} to query id values * @since 1.4.1 */ public CriteriaBuilder createPageIdQuery(int firstResult, int maxResults, String identifierExpression, String... identifierExpressions); /** * Like calling {@link #pageBy(KeysetPage, int, int, String, String...)} and then {@link PaginatedCriteriaBuilder#createPageIdQuery()} but more efficient. * * @param keysetPage The key set from a previous result, may be null * @param firstResult The position of the first result to retrieve, numbered from 0 * @param maxResults The maximum number of results to retrieve * @param identifierExpression The first identifier expression * @param identifierExpressions The other identifier expressions * @return the {@link CriteriaBuilder} to query id values * @since 1.4.1 */ public CriteriaBuilder createPageIdQuery(KeysetPage keysetPage, int firstResult, int maxResults, String identifierExpression, String... identifierExpressions); /* * Join methods */ /** * Adds a join to the query, possibly specializing implicit joins, and giving the joined element an alias. * If fetch is set to true, a join fetch will be added. * * @param path The path to join * @param alias The alias for the joined element * @param type The join type * @param fetch True if a join fetch should be added * @return The query builder for chaining calls */ public X join(String path, String alias, JoinType type, boolean fetch); /** * Adds a join to the query, possibly specializing implicit joins, and giving the joined element an alias. * The resulting join will be the default join meaning that expressions which use the absolute path will refer to this join. * If fetch is set to true, a join fetch will be added. * * @param path The path to join * @param alias The alias for the joined element * @param type The join type * @param fetch True if a join fetch should be added * @return The query builder for chaining calls */ public X joinDefault(String path, String alias, JoinType type, boolean fetch); /** * Like {@link FullQueryBuilder#join(java.lang.String, java.lang.String, com.blazebit.persistence.JoinType, boolean) } but with * {@link JoinType#INNER} and fetch set to true. * * @param path The path to join * @param alias The alias for the joined element * @return The query builder for chaining calls */ public X innerJoinFetch(String path, String alias); /** * Like {@link FullQueryBuilder#joinDefault(java.lang.String, java.lang.String, com.blazebit.persistence.JoinType, boolean) } but with * {@link JoinType#INNER} and fetch set to true. * * @param path The path to join * @param alias The alias for the joined element * @return The query builder for chaining calls */ public X innerJoinFetchDefault(String path, String alias); /** * Like {@link FullQueryBuilder#join(java.lang.String, java.lang.String, com.blazebit.persistence.JoinType, boolean) } but with * {@link JoinType#LEFT} and fetch set to true. * * @param path The path to join * @param alias The alias for the joined element * @return The query builder for chaining calls */ public X leftJoinFetch(String path, String alias); /** * Like {@link FullQueryBuilder#joinDefault(java.lang.String, java.lang.String, com.blazebit.persistence.JoinType, boolean) } but with * {@link JoinType#LEFT} and fetch set to true. * * @param path The path to join * @param alias The alias for the joined element * @return The query builder for chaining calls */ public X leftJoinFetchDefault(String path, String alias); /** * Like {@link FullQueryBuilder#join(java.lang.String, java.lang.String, com.blazebit.persistence.JoinType, boolean) } but with * {@link JoinType#RIGHT} and fetch set to true. * * @param path The path to join * @param alias The alias for the joined element * @return The query builder for chaining calls */ public X rightJoinFetch(String path, String alias); /** * Like {@link FullQueryBuilder#joinDefault(java.lang.String, java.lang.String, com.blazebit.persistence.JoinType, boolean) } but with * {@link JoinType#RIGHT} and fetch set to true. * * @param path The path to join * @param alias The alias for the joined element * @return The query builder for chaining calls */ public X rightJoinFetchDefault(String path, String alias); /* * Select methods */ /** * Starts a {@link SelectObjectBuilder} for the given class. The types of the parameter arguments used in the * {@link SelectObjectBuilder} must match a constructor of the given class. * * @param The new query result type specified by the given class * @param clazz The class which should be used for the select new select clause * @return The select object builder for the given class */ public SelectObjectBuilder> selectNew(Class clazz); /** * Starts a {@link SelectObjectBuilder} for the given constructor. The types of the parameter arguments used in the * {@link SelectObjectBuilder} must match the given constructor. * * @param The new query result type specified by the given class * @param constructor The constructor which should be used for the select new select clause * @return The select object builder for the given class */ public SelectObjectBuilder> selectNew(Constructor constructor); /** * Applies the given object builder to this query. The object builder provides the select clauses and is used to transform the * result set tuples. * * @param The new query result type specified by the given class * @param builder The object builder which transforms the result set into objects of type Y * @return The query builder for chaining calls */ public FullQueryBuilder selectNew(ObjectBuilder builder); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy